chore: update DBIS contracts and integrate EIP-712 helper
- Updated DBIS_ConversionRouter and DBIS_SettlementRouter to utilize IDBIS_EIP712Helper for EIP-712 hashing and signature recovery, improving stack depth management. - Refactored minting logic in DBIS_GRU_MintController to streamline recipient processing. - Enhanced BUILD_NOTES.md with updated build instructions and test coverage details. - Added new functions in DBIS_SignerRegistry for duplicate signer checks and active signer validation. - Introduced a new submodule, DBIS_EIP712Helper, to encapsulate EIP-712 related functionalities. Made-with: Cursor
This commit is contained in:
@@ -4,6 +4,7 @@ pragma solidity ^0.8.20;
|
||||
import "@openzeppelin/contracts/access/AccessControl.sol";
|
||||
import "@openzeppelin/contracts/utils/Pausable.sol";
|
||||
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
|
||||
import "./IDBIS_EIP712Helper.sol";
|
||||
import "./DBIS_RootRegistry.sol";
|
||||
import "./DBIS_SignerRegistry.sol";
|
||||
import "./StablecoinReferenceRegistry.sol";
|
||||
@@ -42,6 +43,7 @@ contract DBIS_ConversionRouter is AccessControl, Pausable, ReentrancyGuard {
|
||||
);
|
||||
|
||||
DBIS_RootRegistry public rootRegistry;
|
||||
address public eip712Helper;
|
||||
mapping(bytes32 => bool) public usedSwapMessageIds;
|
||||
mapping(bytes32 => bool) public venueAllowlist;
|
||||
mapping(address => bool) public quoteIssuerAllowlist;
|
||||
@@ -58,10 +60,11 @@ contract DBIS_ConversionRouter is AccessControl, Pausable, ReentrancyGuard {
|
||||
address quoteIssuer
|
||||
);
|
||||
|
||||
constructor(address admin, address _rootRegistry) {
|
||||
constructor(address admin, address _rootRegistry, address _eip712Helper) {
|
||||
_grantRole(DEFAULT_ADMIN_ROLE, admin);
|
||||
_grantRole(ROUTER_ADMIN_ROLE, admin);
|
||||
rootRegistry = DBIS_RootRegistry(_rootRegistry);
|
||||
eip712Helper = _eip712Helper;
|
||||
}
|
||||
|
||||
function addVenue(bytes32 venue) external onlyRole(ROUTER_ADMIN_ROLE) {
|
||||
@@ -104,28 +107,23 @@ contract DBIS_ConversionRouter is AccessControl, Pausable, ReentrancyGuard {
|
||||
);
|
||||
}
|
||||
|
||||
function _hashSwapAuth(SwapAuth calldata auth) private pure returns (bytes32) {
|
||||
return keccak256(
|
||||
abi.encode(
|
||||
SWAPAUTH_TYPEHASH,
|
||||
auth.messageId,
|
||||
auth.lpaId,
|
||||
auth.venue,
|
||||
auth.tokenIn,
|
||||
auth.tokenOut,
|
||||
auth.amountIn,
|
||||
auth.minAmountOut,
|
||||
auth.deadline,
|
||||
auth.quoteHash,
|
||||
auth.quoteIssuer,
|
||||
auth.chainId,
|
||||
auth.verifyingContract
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function getSwapAuthDigest(SwapAuth calldata auth) external view returns (bytes32) {
|
||||
return keccak256(abi.encodePacked("\x19\x01", _domainSeparator(), _hashSwapAuth(auth)));
|
||||
return IDBIS_EIP712Helper(eip712Helper).getSwapAuthDigest(
|
||||
_domainSeparator(),
|
||||
SWAPAUTH_TYPEHASH,
|
||||
auth.messageId,
|
||||
auth.lpaId,
|
||||
auth.venue,
|
||||
auth.tokenIn,
|
||||
auth.tokenOut,
|
||||
auth.amountIn,
|
||||
auth.minAmountOut,
|
||||
auth.deadline,
|
||||
auth.quoteHash,
|
||||
auth.quoteIssuer,
|
||||
auth.chainId,
|
||||
auth.verifyingContract
|
||||
);
|
||||
}
|
||||
|
||||
function submitSwapAuth(SwapAuth calldata auth, bytes[] calldata signatures, uint256 amountOut) external nonReentrant whenNotPaused {
|
||||
@@ -138,9 +136,26 @@ contract DBIS_ConversionRouter is AccessControl, Pausable, ReentrancyGuard {
|
||||
require(amountOut >= auth.minAmountOut, "DBIS: slippage");
|
||||
_requireStablecoinActive(auth.tokenOut);
|
||||
_requireNotBlocked();
|
||||
address[] memory signers = _recoverSwapSigners(auth, signatures);
|
||||
DBIS_SignerRegistry signerReg = DBIS_SignerRegistry(rootRegistry.getComponent(SIGNER_REGISTRY_KEY));
|
||||
(bool ok, ) = signerReg.validateSignersForSwap(signers, auth.amountIn);
|
||||
bytes32 digest = IDBIS_EIP712Helper(eip712Helper).getSwapAuthDigest(
|
||||
_domainSeparator(),
|
||||
SWAPAUTH_TYPEHASH,
|
||||
auth.messageId,
|
||||
auth.lpaId,
|
||||
auth.venue,
|
||||
auth.tokenIn,
|
||||
auth.tokenOut,
|
||||
auth.amountIn,
|
||||
auth.minAmountOut,
|
||||
auth.deadline,
|
||||
auth.quoteHash,
|
||||
auth.quoteIssuer,
|
||||
auth.chainId,
|
||||
auth.verifyingContract
|
||||
);
|
||||
address[] memory signers = IDBIS_EIP712Helper(eip712Helper).recoverSigners(digest, signatures);
|
||||
require(!DBIS_SignerRegistry(rootRegistry.getComponent(SIGNER_REGISTRY_KEY)).hasDuplicateSigners(signers), "DBIS: duplicate signer");
|
||||
require(DBIS_SignerRegistry(rootRegistry.getComponent(SIGNER_REGISTRY_KEY)).areSignersActiveAtBlock(signers, block.number), "DBIS: signer not active");
|
||||
(bool ok, ) = DBIS_SignerRegistry(rootRegistry.getComponent(SIGNER_REGISTRY_KEY)).validateSignersForSwap(signers, auth.amountIn);
|
||||
require(ok, "DBIS: quorum not met");
|
||||
usedSwapMessageIds[auth.messageId] = true;
|
||||
emit ConversionExecuted(
|
||||
@@ -164,33 +179,4 @@ contract DBIS_ConversionRouter is AccessControl, Pausable, ReentrancyGuard {
|
||||
if (blocklistContract != address(0)) require(!IBlocklist(blocklistContract).isBlocked(msg.sender), "DBIS: blocked");
|
||||
}
|
||||
|
||||
function _recoverSwapSigners(SwapAuth calldata auth, bytes[] calldata signatures) private view returns (address[] memory signers) {
|
||||
DBIS_SignerRegistry signerReg = DBIS_SignerRegistry(rootRegistry.getComponent(SIGNER_REGISTRY_KEY));
|
||||
require(address(signerReg) != address(0), "DBIS: no signer registry");
|
||||
bytes32 digest = keccak256(abi.encodePacked("\x19\x01", _domainSeparator(), _hashSwapAuth(auth)));
|
||||
signers = new address[](signatures.length);
|
||||
for (uint256 i = 0; i < signatures.length; i++) {
|
||||
require(signatures[i].length == 65, "DBIS: bad sig len");
|
||||
address signer = _recover(digest, signatures[i]);
|
||||
require(signer != address(0), "DBIS: invalid sig");
|
||||
require(signerReg.isSignerActiveAtBlock(signer, block.number), "DBIS: signer not active");
|
||||
for (uint256 j = 0; j < i; j++) require(signers[j] != signer, "DBIS: duplicate signer");
|
||||
signers[i] = signer;
|
||||
}
|
||||
}
|
||||
|
||||
function _recover(bytes32 digest, bytes calldata signature) private pure returns (address) {
|
||||
require(signature.length == 65, "DBIS: sig length");
|
||||
bytes32 r;
|
||||
bytes32 s;
|
||||
uint8 v;
|
||||
assembly {
|
||||
r := calldataload(signature.offset)
|
||||
s := calldataload(add(signature.offset, 32))
|
||||
v := byte(0, calldataload(add(signature.offset, 64)))
|
||||
}
|
||||
if (v < 27) v += 27;
|
||||
require(v == 27 || v == 28, "DBIS: invalid v");
|
||||
return ecrecover(digest, v, r, s);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user