Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60a06040 | 17883064 | 454 days ago | IN | 0 ETH | 0.03574603 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
GuardManager
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 99999 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.17; import "@openzeppelin/utils/Strings.sol"; import "@openzeppelin/utils/Address.sol"; import "@solmate/utils/SSTORE2.sol"; import "../interfaces/CommonErrors.sol"; import "../interfaces/IGuardManager.sol"; import "../access/SpoolAccessControllable.sol"; contract GuardManager is IGuardManager, SpoolAccessControllable { using Address for address; /* ========== STATE VARIABLES ========== */ mapping(address => bool) public guardsInitialized; mapping(address => mapping(RequestType => address)) internal guardPointer; constructor(ISpoolAccessControl accessControl) SpoolAccessControllable(accessControl) {} /* ========== EXTERNAL FUNCTIONS ========== */ function runGuards(address smartVaultId, RequestContext calldata context) external view { if (guardPointer[smartVaultId][context.requestType] == address(0)) { return; } GuardDefinition[] memory guards = _readGuards(smartVaultId, context.requestType); for (uint256 i; i < guards.length; ++i) { GuardDefinition memory guard = guards[i]; if (!guard.contractAddress.isContract()) { revert AddressNotContract(guard.contractAddress); } bytes memory encoded = _encodeFunctionCall(smartVaultId, guard, context); (bool success, bytes memory data) = guard.contractAddress.staticcall(encoded); _checkResult(success, data, guard.operator, guard.expectedValue, i); } } function readGuards(address smartVaultId, RequestType requestType) external view returns (GuardDefinition[] memory guards) { return _readGuards(smartVaultId, requestType); } function setGuards(address smartVaultId, GuardDefinition[][] calldata guards, RequestType[] calldata requestTypes) public onlyRole(ROLE_SMART_VAULT_INTEGRATOR, msg.sender) { _guardsNotInitialized(smartVaultId); if (guards.length != requestTypes.length) { revert InvalidArrayLength(); } for (uint256 i; i < requestTypes.length; ++i) { _writeGuards(smartVaultId, requestTypes[i], guards[i]); } guardsInitialized[smartVaultId] = true; emit GuardsInitialized(smartVaultId, guards, requestTypes); } /* ========== INTERNAL FUNCTIONS ========== */ function _guardsNotInitialized(address smartVaultId) internal view { if (guardsInitialized[smartVaultId]) revert GuardsAlreadyInitialized(); } function _readGuards(address smartVaultId, RequestType requestType) internal view returns (GuardDefinition[] memory guards) { if (guardPointer[smartVaultId][requestType] == address(0)) { return new GuardDefinition[](0); } bytes memory value = SSTORE2.read(guardPointer[smartVaultId][requestType]); return abi.decode(value, (GuardDefinition[])); } function _writeGuards(address smartVaultId, RequestType requestType, GuardDefinition[] calldata guards) internal { if (guards.length == 0) { revert IncompleteGuardDefinition(); } if (guards.length > MAX_GUARD_COUNT) { revert TooManyGuards(); } for (uint256 i; i < guards.length; ++i) { if (guards[i].contractAddress == address(0) || bytes(guards[i].methodSignature).length == 0) { revert IncompleteGuardDefinition(); } } address key = SSTORE2.write(abi.encode(guards)); guardPointer[smartVaultId][requestType] = key; } function _checkResult(bool success, bytes memory returnValue, bytes2 operator, uint256 value, uint256 guardNum) internal pure { if (!success) revert GuardError(); bool result = true; if (operator == bytes2("==")) { result = abi.decode(returnValue, (uint256)) == value; } else if (operator == bytes2("<=")) { result = abi.decode(returnValue, (uint256)) <= value; } else if (operator == bytes2(">=")) { result = abi.decode(returnValue, (uint256)) >= value; } else if (operator == bytes2("<")) { result = abi.decode(returnValue, (uint256)) < value; } else if (operator == bytes2(">")) { result = abi.decode(returnValue, (uint256)) > value; } else { result = abi.decode(returnValue, (bool)); } if (!result) revert GuardFailed(guardNum); } /** * @notice Resolve parameter values to be used in the guard function call and encode * together with methodID. * @dev As specified in https://docs.soliditylang.org/en/v0.8.17/abi-spec.html#use-of-dynamic-types */ function _encodeFunctionCall(address smartVaultId, GuardDefinition memory guard, RequestContext memory context) internal pure returns (bytes memory) { bytes4 methodID = bytes4(keccak256(abi.encodePacked(guard.methodSignature))); uint256 paramsLength = guard.methodParamTypes.length; bytes memory result = new bytes(0); result = bytes.concat(result, methodID); uint16 customValueIdx = 0; uint256 paramsEndLoc = paramsLength * 32; // Loop through parameters and // - store values for simple types // - store param value location for dynamic types for (uint256 i; i < paramsLength; ++i) { GuardParamType paramType = guard.methodParamTypes[i]; if (paramType == GuardParamType.DynamicCustomValue) { result = bytes.concat(result, abi.encode(paramsEndLoc)); paramsEndLoc += 32 + guard.methodParamValues[customValueIdx].length; customValueIdx++; } else if (paramType == GuardParamType.CustomValue) { result = bytes.concat(result, guard.methodParamValues[customValueIdx]); customValueIdx++; } else if (paramType == GuardParamType.VaultAddress) { result = bytes.concat(result, abi.encode(smartVaultId)); } else if (paramType == GuardParamType.Receiver) { result = bytes.concat(result, abi.encode(context.receiver)); } else if (paramType == GuardParamType.Executor) { result = bytes.concat(result, abi.encode(context.executor)); } else if (paramType == GuardParamType.Owner) { result = bytes.concat(result, abi.encode(context.owner)); } else if (paramType == GuardParamType.Assets) { result = bytes.concat(result, abi.encode(paramsEndLoc)); paramsEndLoc += 32 + context.assets.length * 32; } else if (paramType == GuardParamType.Tokens) { result = bytes.concat(result, abi.encode(paramsEndLoc)); paramsEndLoc += 32 + context.tokens.length * 32; } else { revert InvalidGuardParamType(uint256(paramType)); } } // Loop through params again and store values for dynamic types. customValueIdx = 0; for (uint256 i; i < paramsLength; ++i) { GuardParamType paramType = guard.methodParamTypes[i]; if (paramType == GuardParamType.DynamicCustomValue) { result = bytes.concat(result, abi.encode(guard.methodParamValues[customValueIdx].length / 32)); result = bytes.concat(result, guard.methodParamValues[customValueIdx]); customValueIdx++; } else if (paramType == GuardParamType.CustomValue) { customValueIdx++; } else if (paramType == GuardParamType.Assets) { result = bytes.concat(result, abi.encode(context.assets.length)); result = bytes.concat(result, abi.encodePacked(context.assets)); } else if (paramType == GuardParamType.Tokens) { result = bytes.concat(result, abi.encode(context.tokens.length)); result = bytes.concat(result, abi.encodePacked(context.tokens)); } } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; import "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Read and write to persistent storage at a fraction of the cost. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SSTORE2.sol) /// @author Modified from 0xSequence (https://github.com/0xSequence/sstore2/blob/master/contracts/SSTORE2.sol) library SSTORE2 { uint256 internal constant DATA_OFFSET = 1; // We skip the first byte as it's a STOP opcode to ensure the contract can't be called. /*////////////////////////////////////////////////////////////// WRITE LOGIC //////////////////////////////////////////////////////////////*/ function write(bytes memory data) internal returns (address pointer) { // Prefix the bytecode with a STOP opcode to ensure it cannot be called. bytes memory runtimeCode = abi.encodePacked(hex"00", data); bytes memory creationCode = abi.encodePacked( //---------------------------------------------------------------------------------------------------------------// // Opcode | Opcode + Arguments | Description | Stack View // //---------------------------------------------------------------------------------------------------------------// // 0x60 | 0x600B | PUSH1 11 | codeOffset // // 0x59 | 0x59 | MSIZE | 0 codeOffset // // 0x81 | 0x81 | DUP2 | codeOffset 0 codeOffset // // 0x38 | 0x38 | CODESIZE | codeSize codeOffset 0 codeOffset // // 0x03 | 0x03 | SUB | (codeSize - codeOffset) 0 codeOffset // // 0x80 | 0x80 | DUP | (codeSize - codeOffset) (codeSize - codeOffset) 0 codeOffset // // 0x92 | 0x92 | SWAP3 | codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) // // 0x59 | 0x59 | MSIZE | 0 codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) // // 0x39 | 0x39 | CODECOPY | 0 (codeSize - codeOffset) // // 0xf3 | 0xf3 | RETURN | // //---------------------------------------------------------------------------------------------------------------// hex"60_0B_59_81_38_03_80_92_59_39_F3", // Returns all code in the contract except for the first 11 (0B in hex) bytes. runtimeCode // The bytecode we want the contract to have after deployment. Capped at 1 byte less than the code size limit. ); /// @solidity memory-safe-assembly assembly { // Deploy a new contract with the generated creation code. // We start 32 bytes into the code to avoid copying the byte length. pointer := create(0, add(creationCode, 32), mload(creationCode)) } require(pointer != address(0), "DEPLOYMENT_FAILED"); } /*////////////////////////////////////////////////////////////// READ LOGIC //////////////////////////////////////////////////////////////*/ function read(address pointer) internal view returns (bytes memory) { return readBytecode(pointer, DATA_OFFSET, pointer.code.length - DATA_OFFSET); } function read(address pointer, uint256 start) internal view returns (bytes memory) { start += DATA_OFFSET; return readBytecode(pointer, start, pointer.code.length - start); } function read( address pointer, uint256 start, uint256 end ) internal view returns (bytes memory) { start += DATA_OFFSET; end += DATA_OFFSET; require(pointer.code.length >= end, "OUT_OF_BOUNDS"); return readBytecode(pointer, start, end - start); } /*////////////////////////////////////////////////////////////// INTERNAL HELPER LOGIC //////////////////////////////////////////////////////////////*/ function readBytecode( address pointer, uint256 start, uint256 size ) private view returns (bytes memory data) { /// @solidity memory-safe-assembly assembly { // Get a pointer to some free memory. data := mload(0x40) // Update the free memory pointer to prevent overriding our data. // We use and(x, not(31)) as a cheaper equivalent to sub(x, mod(x, 32)). // Adding 31 to size and running the result through the logic above ensures // the memory pointer remains word-aligned, following the Solidity convention. mstore(0x40, add(data, and(add(add(size, 32), 31), not(31)))) // Store the size of the data in the first 32 byte chunk of free memory. mstore(data, size) // Copy the code into memory right after the 32 bytes we used to store the size. extcodecopy(pointer, add(data, 32), start, size) } } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.17; /** * @notice Used when an array has invalid length. */ error InvalidArrayLength(); /** * @notice Used when group of smart vaults or strategies do not have same asset group. */ error NotSameAssetGroup(); /** * @notice Used when configuring an address with a zero address. */ error ConfigurationAddressZero(); /** * @notice Used when constructor or intializer parameters are invalid. */ error InvalidConfiguration(); /** * @notice Used when fetched exchange rate is out of slippage range. */ error ExchangeRateOutOfSlippages(); /** * @notice Used when an invalid strategy is provided. * @param address_ Address of the invalid strategy. */ error InvalidStrategy(address address_); /** * @notice Used when doing low-level call on an address that is not a contract. * @param address_ Address of the contract */ error AddressNotContract(address address_); /** * @notice Used when invoking an only view execution and tx.origin is not address zero. * @param address_ Address of the tx.origin */ error OnlyViewExecution(address address_);
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.17; import "./ISmartVault.sol"; import "./RequestType.sol"; error GuardsAlreadyInitialized(); error GuardsNotInitialized(); error GuardError(); /** * @notice Used when a guard fails. * @param guardNum Sequential number of the guard that failed. */ error GuardFailed(uint256 guardNum); error InvalidGuardParamType(uint256 paramType); /** * @notice Too many guard definitions have been passed when creating a vault. */ error TooManyGuards(); /** * @notice The guard definition does not have all required inputs */ error IncompleteGuardDefinition(); /** * @custom:member VaultAddress Address of the smart vault. * @custom:member Executor In case of deposit, executor of deposit action; in case of withdrawal, executor of redeem action. * @custom:member Receiver Receiver of receipt NFT. * @custom:member Owner In case of deposit, owner of assets; in case of withdrawal, owner of vault shares. * @custom:member Assets Amounts of assets involved. * @custom:member Tokens Addresses of assets involved. * @custom:member AssetGroup Asset group of the smart vault. * @custom:member CustomValue Custom value. * @custom:member DynamicCustomValue Dynamic custom value. */ enum GuardParamType { VaultAddress, Executor, Receiver, Owner, Assets, Tokens, AssetGroup, CustomValue, DynamicCustomValue } /** * @custom:member methodSignature Signature of the method to invoke * @custom:member contractAddress Address of the contract to invoke * @custom:member operator The operator to use when comparing expectedValue to guard's function result. * @custom:member expectedValue Value to use when comparing with the guard function result. * - System only supports guards with return values that can be cast to uint256. * @custom:member methodParamTypes Types of parameters that the guard function is expecting. * @custom:member methodParamValues Parameter values that will be passed into the guard function call. * - This array should only include fixed/static values. Parameters that are resolved at runtime should be omitted. * - All values should be encoded using "abi.encode" before passing them to the GuardManager contract. * - We assume that all static types are encoded to 32 bytes. Fixed-size static arrays and structs with only static * type members are not supported. * - If empty, system will assume the expected value is bool(true). */ struct GuardDefinition { string methodSignature; address contractAddress; bytes2 operator; uint256 expectedValue; GuardParamType[] methodParamTypes; bytes[] methodParamValues; } /** * @custom:member receiver Receiver of receipt NFT. * @custom:member executor In case of deposit, executor of deposit action; in case of withdrawal, executor of redeem action. * @custom:member owner In case of deposit, owner of assets; in case of withdrawal, owner of vault shares. * @custom:member requestType Request type for which the guard is run. * @custom:member assets Amounts of assets involved. * @custom:member tokens Addresses of tokens involved. */ struct RequestContext { address receiver; address executor; address owner; RequestType requestType; uint256[] assets; address[] tokens; } interface IGuardManager { /** * @notice Runs guards for a smart vault. * @dev Reverts if any guard fails. * The context.methodParamValues array should only include fixed/static values. * Parameters that are resolved at runtime should be omitted. All values should be encoded using "abi.encode" before * passing them to the GuardManager contract. We assume that all static types are encoded to 32 bytes. Fixed-size * static arrays and structs with only static type members are not supported. * @param smartVault Smart vault for which to run the guards. * @param context Context for running the guards. */ function runGuards(address smartVault, RequestContext calldata context) external view; /** * @notice Gets guards for smart vault and request type. * @param smartVault Smart vault for which to get guards. * @param requestType Request type for which to get guards. * @return guards Guards for the smart vault and request type. */ function readGuards(address smartVault, RequestType requestType) external view returns (GuardDefinition[] memory guards); /** * @notice Sets guards for the smart vault. * @dev * @dev Requirements: * - caller must have role ROLE_SMART_VAULT_INTEGRATOR * - guards should not have been already set for the smart vault * @param smartVault Smart vault for which to set the guards. * @param guards Guards to set. Grouped by the request types. * @param requestTypes Request types for groups of guards. */ function setGuards(address smartVault, GuardDefinition[][] calldata guards, RequestType[] calldata requestTypes) external; /** * @notice Emitted when guards are set for a smart vault. * @param smartVault Smart vault for which guards were set. * @param guards Guard definitions * @param requestTypes Guard triggers */ event GuardsInitialized(address indexed smartVault, GuardDefinition[][] guards, RequestType[] requestTypes); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.17; import "../interfaces/ISpoolAccessControl.sol"; import "../interfaces/CommonErrors.sol"; import "./Roles.sol"; /** * @notice Account access role verification middleware */ abstract contract SpoolAccessControllable { /* ========== CONSTANTS ========== */ /** * @dev Spool access control manager. */ ISpoolAccessControl internal immutable _accessControl; /* ========== CONSTRUCTOR ========== */ /** * @param accessControl_ Spool access control manager. */ constructor(ISpoolAccessControl accessControl_) { if (address(accessControl_) == address(0)) revert ConfigurationAddressZero(); _accessControl = accessControl_; } /* ========== INTERNAL FUNCTIONS ========== */ /** * @dev Reverts if an account is missing a role.\ * @param role Role to check for. * @param account Account to check. */ function _checkRole(bytes32 role, address account) internal view virtual { if (!_accessControl.hasRole(role, account)) { revert MissingRole(role, account); } } /** * @dev Revert if an account is missing a role for a smartVault. * @param smartVault Address of the smart vault. * @param role Role to check for. * @param account Account to check. */ function _checkSmartVaultRole(address smartVault, bytes32 role, address account) internal view { if (!_accessControl.hasSmartVaultRole(smartVault, role, account)) { revert MissingRole(role, account); } } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { if (_accessControl.paused()) { revert SystemPaused(); } } function _checkNonReentrant() internal view { _accessControl.checkNonReentrant(); } function _nonReentrantBefore() internal { _accessControl.nonReentrantBefore(); } function _nonReentrantAfter() internal { _accessControl.nonReentrantAfter(); } /* ========== MODIFIERS ========== */ /** * @notice Only allows accounts with granted role. * @dev Reverts when the account fails check. * @param role Role to check for. * @param account Account to check. */ modifier onlyRole(bytes32 role, address account) { _checkRole(role, account); _; } /** * @notice Only allows accounts with granted role for a smart vault. * @dev Reverts when the account fails check. * @param smartVault Address of the smart vault. * @param role Role to check for. * @param account Account to check. */ modifier onlySmartVaultRole(address smartVault, bytes32 role, address account) { _checkSmartVaultRole(smartVault, role, account); _; } /** * @notice Only allows accounts that are Spool admins or admins of a smart vault. * @dev Reverts when the account fails check. * @param smartVault Address of the smart vault. * @param account Account to check. */ modifier onlyAdminOrVaultAdmin(address smartVault, address account) { _accessControl.checkIsAdminOrVaultAdmin(smartVault, account); _; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Prevents a contract from calling itself, or other contracts using this modifier. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } /** * @dev Check if a system has already entered in the non-reentrant state. */ modifier checkNonReentrant() { _checkNonReentrant(); _; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.17; import "@openzeppelin-upgradeable/token/ERC1155/IERC1155Upgradeable.sol"; import "@openzeppelin-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import "@openzeppelin-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol"; import "./Constants.sol"; import "./RequestType.sol"; /* ========== ERRORS ========== */ /** * @notice Used when the ID for deposit NFTs overflows. * @dev Should never happen. */ error DepositIdOverflow(); /** * @notice Used when the ID for withdrawal NFTs overflows. * @dev Should never happen. */ error WithdrawalIdOverflow(); /** * @notice Used when ID does not represent a deposit NFT. * @param depositNftId Invalid ID for deposit NFT. */ error InvalidDepositNftId(uint256 depositNftId); /** * @notice Used when ID does not represent a withdrawal NFT. * @param withdrawalNftId Invalid ID for withdrawal NFT. */ error InvalidWithdrawalNftId(uint256 withdrawalNftId); /** * @notice Used when balance of the NFT is invalid. * @param balance Actual balance of the NFT. */ error InvalidNftBalance(uint256 balance); /** * @notice Used when someone wants to transfer invalid NFT shares amount. * @param transferAmount Amount of shares requested to be transferred. */ error InvalidNftTransferAmount(uint256 transferAmount); /** * @notice Used when user tries to send tokens to himself. */ error SenderEqualsRecipient(); /* ========== STRUCTS ========== */ struct DepositMetadata { uint256[] assets; uint256 initiated; uint256 flushIndex; } /** * @notice Holds metadata detailing the withdrawal behind the NFT. * @custom:member vaultShares Vault shares withdrawn. * @custom:member flushIndex Flush index into which withdrawal is included. */ struct WithdrawalMetadata { uint256 vaultShares; uint256 flushIndex; } /** * @notice Holds all smart vault fee percentages. * @custom:member managementFeePct Management fee of the smart vault. * @custom:member depositFeePct Deposit fee of the smart vault. * @custom:member performanceFeePct Performance fee of the smart vault. */ struct SmartVaultFees { uint16 managementFeePct; uint16 depositFeePct; uint16 performanceFeePct; } /* ========== INTERFACES ========== */ interface ISmartVault is IERC20Upgradeable, IERC1155MetadataURIUpgradeable { /* ========== EXTERNAL VIEW FUNCTIONS ========== */ /** * @notice Fractional balance of a NFT (0 - NFT_MINTED_SHARES). * @param account Account to check the balance for. * @param id ID of the NFT to check. * @return fractionalBalance Fractional balance of account for the NFT. */ function balanceOfFractional(address account, uint256 id) external view returns (uint256 fractionalBalance); /** * @notice Fractional balance of a NFTs (0 - NFT_MINTED_SHARES). * @param account Account to check the balance for. * @param ids IDs of the NFTs to check. * @return fractionalBalances Fractional balances of account for each requested NFT. */ function balanceOfFractionalBatch(address account, uint256[] calldata ids) external view returns (uint256[] memory fractionalBalances); /** * @notice Gets the asset group used by the smart vault. * @return id ID of the asset group. */ function assetGroupId() external view returns (uint256 id); /** * @notice Gets the name of the smart vault. * @return name Name of the vault. */ function vaultName() external view returns (string memory name); /** * @notice Gets metadata for NFTs. * @param nftIds IDs of NFTs. * @return metadata Metadata for each requested NFT. */ function getMetadata(uint256[] calldata nftIds) external view returns (bytes[] memory metadata); /* ========== EXTERNAL MUTATIVE FUNCTIONS ========== */ /** * @notice Set a new base URI for ERC1155 metadata. * @param uri_ new base URI value */ function setBaseURI(string memory uri_) external; /** * @notice Mints smart vault tokens for receiver. * @dev Requirements: * - caller must have role ROLE_SMART_VAULT_MANAGER * @param receiver REceiver of minted tokens. * @param vaultShares Amount of tokens to mint. */ function mintVaultShares(address receiver, uint256 vaultShares) external; /** * @notice Burns smart vault tokens and releases strategy shares back to strategies. * @dev Requirements: * - caller must have role ROLE_SMART_VAULT_MANAGER * @param owner Address for which to burn the tokens. * @param vaultShares Amount of tokens to burn. * @param strategies Strategies for which to release the strategy shares. * @param shares Amounts of strategy shares to release. */ function burnVaultShares( address owner, uint256 vaultShares, address[] calldata strategies, uint256[] calldata shares ) external; /** * @notice Mints a new withdrawal NFT. * @dev Supply of minted NFT is NFT_MINTED_SHARES (for partial burning). * Requirements: * - caller must have role ROLE_SMART_VAULT_MANAGER * @param receiver Address that will receive the NFT. * @param metadata Metadata to store for minted NFT. * @return id ID of the minted NFT. */ function mintWithdrawalNFT(address receiver, WithdrawalMetadata calldata metadata) external returns (uint256 id); /** * @notice Mints a new deposit NFT. * @dev Supply of minted NFT is NFT_MINTED_SHARES (for partial burning). * Requirements: * - caller must have role ROLE_SMART_VAULT_MANAGER * @param receiver Address that will receive the NFT. * @param metadata Metadata to store for minted NFT. * @return id ID of the minted NFT. */ function mintDepositNFT(address receiver, DepositMetadata calldata metadata) external returns (uint256 id); /** * @notice Burns NFTs and returns their metadata. * Allows for partial burning. * @dev Requirements: * - caller must have role ROLE_SMART_VAULT_MANAGER * @param owner Owner of NFTs to burn. * @param nftIds IDs of NFTs to burn. * @param nftAmounts NFT shares to burn (partial burn). * @return metadata Metadata for each burned NFT. */ function burnNFTs(address owner, uint256[] calldata nftIds, uint256[] calldata nftAmounts) external returns (bytes[] memory metadata); /** * @notice Transfers smart vault tokens. * @dev Requirements: * - caller must have role ROLE_SMART_VAULT_MANAGER * @param from Spender and owner of tokens. * @param to Address to which tokens will be transferred. * @param amount Amount of tokens to transfer. * @return success True if transfer was successful. */ function transferFromSpender(address from, address to, uint256 amount) external returns (bool success); /** * @notice Transfers unclaimed shares to claimer. * @dev Requirements: * - caller must have role ROLE_SMART_VAULT_MANAGER * @param claimer Address that claims the shares. * @param amount Amount of shares to transfer. */ function claimShares(address claimer, uint256 amount) external; /// @notice Emitted when base URI is changed. event BaseURIChanged(string baseUri); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.17; /** * @notice Different request types for guards and actions. * @custom:member Deposit User is depositing into a smart vault. * @custom:member Withdrawal User is requesting withdrawal from a smart vault. * @custom:member TransferNFT User is transfering deposit or withdrawal NFT. * @custom:member BurnNFT User is burning deposit or withdrawal NFT. * @custom:member TransferSVTs User is transferring smart vault tokens. */ enum RequestType { Deposit, Withdrawal, TransferNFT, BurnNFT, TransferSVTs }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.17; import "@openzeppelin-upgradeable/access/IAccessControlUpgradeable.sol"; /** * @notice Used when an account is missing a required role. * @param role Required role. * @param account Account missing the required role. */ error MissingRole(bytes32 role, address account); /** * @notice Used when interacting with Spool when the system is paused. */ error SystemPaused(); /** * @notice Used when setting smart vault owner */ error SmartVaultOwnerAlreadySet(address smartVault); /** * @notice Used when a contract tries to enter in a non-reentrant state. */ error ReentrantCall(); /** * @notice Used when a contract tries to call in a non-reentrant function and doesn't have the correct role. */ error NoReentrantRole(); interface ISpoolAccessControl is IAccessControlUpgradeable { /* ========== VIEW FUNCTIONS ========== */ /** * @notice Gets owner of a smart vault. * @param smartVault Smart vault. * @return owner Owner of the smart vault. */ function smartVaultOwner(address smartVault) external view returns (address owner); /** * @notice Looks if an account has a role for a smart vault. * @param smartVault Address of the smart vault. * @param role Role to look for. * @param account Account to check. * @return hasRole True if account has the role for the smart vault, false otherwise. */ function hasSmartVaultRole(address smartVault, bytes32 role, address account) external view returns (bool hasRole); /** * @notice Checks if an account is either Spool admin or admin for a smart vault. * @dev The function reverts if account is neither. * @param smartVault Address of the smart vault. * @param account to check. */ function checkIsAdminOrVaultAdmin(address smartVault, address account) external view; /** * @notice Checks if system is paused or not. * @return isPaused True if system is paused, false otherwise. */ function paused() external view returns (bool isPaused); /* ========== MUTATIVE FUNCTIONS ========== */ /** * @notice Pauses the whole system. * @dev Requirements: * - caller must have role ROLE_PAUSER */ function pause() external; /** * @notice Unpauses the whole system. * @dev Requirements: * - caller must have role ROLE_UNPAUSER */ function unpause() external; /** * @notice Grants role to an account for a smart vault. * @dev Requirements: * - caller must have either role ROLE_SPOOL_ADMIN or role ROLE_SMART_VAULT_ADMIN for the smart vault * @param smartVault Address of the smart vault. * @param role Role to grant. * @param account Account to grant the role to. */ function grantSmartVaultRole(address smartVault, bytes32 role, address account) external; /** * @notice Revokes role from an account for a smart vault. * @dev Requirements: * - caller must have either role ROLE_SPOOL_ADMIN or role ROLE_SMART_VAULT_ADMIN for the smart vault * @param smartVault Address of the smart vault. * @param role Role to revoke. * @param account Account to revoke the role from. */ function revokeSmartVaultRole(address smartVault, bytes32 role, address account) external; /** * @notice Renounce role for a smart vault. * @param smartVault Address of the smart vault. * @param role Role to renounce. */ function renounceSmartVaultRole(address smartVault, bytes32 role) external; /** * @notice Grant ownership to smart vault and assigns admin role. * @dev Ownership can only be granted once and it should be done at vault creation time. * @param smartVault Address of the smart vault. * @param owner address to which grant ownership to */ function grantSmartVaultOwnership(address smartVault, address owner) external; /** * @notice Checks and reverts if a system has already entered in the non-reentrant state. */ function checkNonReentrant() external view; /** * @notice Sets the entered flag to true when entering for the first time. * @dev Reverts if a system has already entered before. */ function nonReentrantBefore() external; /** * @notice Resets the entered flag after the call is finished. */ function nonReentrantAfter() external; /** * @notice Emitted when ownership of a smart vault is granted to an address * @param smartVault Smart vault address * @param address_ Address of the new smart vault owner */ event SmartVaultOwnershipGranted(address indexed smartVault, address indexed address_); /** * @notice Smart vault specific role was granted * @param smartVault Smart vault address * @param role Role ID * @param account Account to which the role was granted */ event SmartVaultRoleGranted(address indexed smartVault, bytes32 indexed role, address indexed account); /** * @notice Smart vault specific role was revoked * @param smartVault Smart vault address * @param role Role ID * @param account Account for which the role was revoked */ event SmartVaultRoleRevoked(address indexed smartVault, bytes32 indexed role, address indexed account); /** * @notice Smart vault specific role was renounced * @param smartVault Smart vault address * @param role Role ID * @param account Account that renounced the role */ event SmartVaultRoleRenounced(address indexed smartVault, bytes32 indexed role, address indexed account); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.17; /** * @dev Grants permission to: * - acts as a default admin for other roles, * - can whitelist an action with action manager, * - can manage asset group registry. * * Is granted to the deployer of the SpoolAccessControl contract. * * Equals to the DEFAULT_ADMIN_ROLE of the OpenZeppelin AccessControl. */ bytes32 constant ROLE_SPOOL_ADMIN = 0x00; /** * @dev Grants permission to integrate a new smart vault into the Spool ecosystem. * * Should be granted to smart vault factory contracts. */ bytes32 constant ROLE_SMART_VAULT_INTEGRATOR = keccak256("SMART_VAULT_INTEGRATOR"); /** * @dev Grants permission to * - manage rewards on smart vaults, * - manage roles on smart vaults, * - redeem for another user of a smart vault. */ bytes32 constant ROLE_SMART_VAULT_ADMIN = keccak256("SMART_VAULT_ADMIN"); /** * @dev Grants permission to manage allowlists with AllowlistGuard for a smart vault. * * Should be granted to whoever is in charge of maintaining allowlists with AllowlistGuard for a smart vault. */ bytes32 constant ROLE_GUARD_ALLOWLIST_MANAGER = keccak256("GUARD_ALLOWLIST_MANAGER"); /** * @dev Grants permission to manage assets on master wallet. * * Should be granted to: * - the SmartVaultManager contract, * - the StrategyRegistry contract, * - the DepositManager contract, * - the WithdrawalManager contract. */ bytes32 constant ROLE_MASTER_WALLET_MANAGER = keccak256("MASTER_WALLET_MANAGER"); /** * @dev Marks a contract as a smart vault manager. * * Should be granted to: * - the SmartVaultManager contract, * - the DepositManager contract. */ bytes32 constant ROLE_SMART_VAULT_MANAGER = keccak256("SMART_VAULT_MANAGER"); /** * @dev Marks a contract as a strategy registry. * * Should be granted to the StrategyRegistry contract. */ bytes32 constant ROLE_STRATEGY_REGISTRY = keccak256("STRATEGY_REGISTRY"); /** * @dev Grants permission to act as a risk provider. * * Should be granted to whoever is allowed to provide risk scores. */ bytes32 constant ROLE_RISK_PROVIDER = keccak256("RISK_PROVIDER"); /** * @dev Grants permission to act as an allocation provider. * * Should be granted to contracts that are allowed to calculate allocations. */ bytes32 constant ROLE_ALLOCATION_PROVIDER = keccak256("ALLOCATION_PROVIDER"); /** * @dev Grants permission to pause the system. */ bytes32 constant ROLE_PAUSER = keccak256("SYSTEM_PAUSER"); /** * @dev Grants permission to unpause the system. */ bytes32 constant ROLE_UNPAUSER = keccak256("SYSTEM_UNPAUSER"); /** * @dev Grants permission to manage rewards payment pool. */ bytes32 constant ROLE_REWARD_POOL_ADMIN = keccak256("REWARD_POOL_ADMIN"); /** * @dev Grants permission to reallocate smart vaults. */ bytes32 constant ROLE_REALLOCATOR = keccak256("REALLOCATOR"); /** * @dev Grants permission to be used as a strategy. */ bytes32 constant ROLE_STRATEGY = keccak256("STRATEGY"); /** * @dev Grants permission to manually set strategy apy. */ bytes32 constant ROLE_STRATEGY_APY_SETTER = keccak256("STRATEGY_APY_SETTER"); /** * @dev Grants permission to manage role ROLE_STRATEGY. */ bytes32 constant ADMIN_ROLE_STRATEGY = keccak256("ADMIN_STRATEGY"); /** * @dev Grants permission vault admins to allow redeem on behalf of other users. */ bytes32 constant ROLE_SMART_VAULT_ALLOW_REDEEM = keccak256("SMART_VAULT_ALLOW_REDEEM"); /** * @dev Grants permission to manage role ROLE_SMART_VAULT_ALLOW_REDEEM. */ bytes32 constant ADMIN_ROLE_SMART_VAULT_ALLOW_REDEEM = keccak256("ADMIN_SMART_VAULT_ALLOW_REDEEM"); /** * @dev Grants permission to run do hard work. */ bytes32 constant ROLE_DO_HARD_WORKER = keccak256("DO_HARD_WORKER"); /** * @dev Grants permission to immediately withdraw assets in case of emergency. */ bytes32 constant ROLE_EMERGENCY_WITHDRAWAL_EXECUTOR = keccak256("EMERGENCY_WITHDRAWAL_EXECUTOR"); /** * @dev Grants permission to swap with swapper. * * Should be granted to the DepositSwap contract. */ bytes32 constant ROLE_SWAPPER = keccak256("SWAPPER");
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165Upgradeable.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155Upgradeable is IERC165Upgradeable { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol) pragma solidity ^0.8.0; import "../IERC1155Upgradeable.sol"; /** * @dev Interface of the optional ERC1155MetadataExtension interface, as defined * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP]. * * _Available since v3.1._ */ interface IERC1155MetadataURIUpgradeable is IERC1155Upgradeable { /** * @dev Returns the URI for token type `id`. * * If the `\{id\}` substring is present in the URI, it must be replaced by * clients with the actual token type ID. */ function uri(uint256 id) external view returns (string memory); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.17; /// @dev Number of seconds in an average year. uint256 constant SECONDS_IN_YEAR = 31_556_926; /// @dev Number of seconds in an average year. int256 constant SECONDS_IN_YEAR_INT = 31_556_926; /// @dev Represents 100%. uint256 constant FULL_PERCENT = 100_00; /// @dev Represents 100%. int256 constant FULL_PERCENT_INT = 100_00; /// @dev Represents 100% for yield. int256 constant YIELD_FULL_PERCENT_INT = 10 ** 12; /// @dev Represents 100% for yield. uint256 constant YIELD_FULL_PERCENT = uint256(YIELD_FULL_PERCENT_INT); /// @dev Maximal management fee that can be set on a smart vault. Expressed in terms of FULL_PERCENT. uint256 constant MANAGEMENT_FEE_MAX = 5_00; /// @dev Maximal deposit fee that can be set on a smart vault. Expressed in terms of FULL_PERCENT. uint256 constant DEPOSIT_FEE_MAX = 5_00; /// @dev Maximal smart vault performance fee that can be set on a smart vault. Expressed in terms of FULL_PERCENT. uint256 constant SV_PERFORMANCE_FEE_MAX = 20_00; /// @dev Maximal ecosystem fee that can be set on the system. Expressed in terms of FULL_PERCENT. uint256 constant ECOSYSTEM_FEE_MAX = 20_00; /// @dev Maximal treasury fee that can be set on the system. Expressed in terms of FULL_PERCENT. uint256 constant TREASURY_FEE_MAX = 10_00; /// @dev Maximal risk score a strategy can be assigned. uint8 constant MAX_RISK_SCORE = 10_0; /// @dev Minimal risk score a strategy can be assigned. uint8 constant MIN_RISK_SCORE = 1; /// @dev Maximal value for risk tolerance a smart vautl can have. int8 constant MAX_RISK_TOLERANCE = 10; /// @dev Minimal value for risk tolerance a smart vault can have. int8 constant MIN_RISK_TOLERANCE = -10; /// @dev If set as risk provider, system will return fixed risk score values address constant STATIC_RISK_PROVIDER = address(0xaaa); /// @dev Fixed values to use if risk provider is set to STATIC_RISK_PROVIDER uint8 constant STATIC_RISK_SCORE = 1; /// @dev Maximal value of deposit NFT ID. uint256 constant MAXIMAL_DEPOSIT_ID = 2 ** 255; /// @dev Maximal value of withdrawal NFT ID. uint256 constant MAXIMAL_WITHDRAWAL_ID = 2 ** 256 - 1; /// @dev How many shares will be minted with a NFT uint256 constant NFT_MINTED_SHARES = 10 ** 6; /// @dev Each smart vault can have up to STRATEGY_COUNT_CAP strategies. uint256 constant STRATEGY_COUNT_CAP = 16; /// @dev Maximal DHW base yield. Expressed in terms of FULL_PERCENT. uint256 constant MAX_DHW_BASE_YIELD_LIMIT = 10_00; /// @dev Smart vault and strategy share multiplier at first deposit. uint256 constant INITIAL_SHARE_MULTIPLIER = 1000; /// @dev Strategy initial locked shares. These shares will never be unlocked. uint256 constant INITIAL_LOCKED_SHARES = 10 ** 12; /// @dev Strategy initial locked shares address. address constant INITIAL_LOCKED_SHARES_ADDRESS = address(0xdead); /// @dev Maximum number of guards a smart vault can be configured with uint256 constant MAX_GUARD_COUNT = 10; /// @dev Maximum number of actions a smart vault can be configured with uint256 constant MAX_ACTION_COUNT = 10; /// @dev ID of null asset group. Should not be used by any strategy or smart vault. uint256 constant NULL_ASSET_GROUP_ID = 0;
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControlUpgradeable { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165Upgradeable { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
{ "remappings": [ "@openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", "@openzeppelin/=lib/openzeppelin-contracts/contracts/", "@solmate/=lib/solmate/src/", "create3/=lib/create3/contracts/", "ds-test/=lib/forge-std/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "solmate/=lib/solmate/src/", "sstore2/=lib/sstore2/contracts/", "lib/forge-std:ds-test/=lib/forge-std/lib/ds-test/src/", "lib/openzeppelin-contracts:ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/", "lib/openzeppelin-contracts:erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "lib/openzeppelin-contracts:forge-std/=lib/openzeppelin-contracts/lib/forge-std/src/", "lib/openzeppelin-contracts-upgradeable:ds-test/=lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/src/", "lib/openzeppelin-contracts-upgradeable:forge-std/=lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/", "lib/solmate:ds-test/=lib/solmate/lib/ds-test/src/" ], "optimizer": { "enabled": true, "runs": 99999 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": { "script/helper/ArraysHelper.sol": { "ArraysHelper": "0x92076039b4b69576e99e338899f76dfc19f6b18c" }, "src/libraries/ArrayMapping.sol": { "ArrayMappingUint256": "0x5589c1a93ad9c910eeb31496f514b0def2cc0b3d" }, "src/libraries/SpoolUtils.sol": { "SpoolUtils": "0xee2748274586db8e4a227f39b1fd95f5ed35d81e" } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract ISpoolAccessControl","name":"accessControl","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"address_","type":"address"}],"name":"AddressNotContract","type":"error"},{"inputs":[],"name":"ConfigurationAddressZero","type":"error"},{"inputs":[],"name":"GuardError","type":"error"},{"inputs":[{"internalType":"uint256","name":"guardNum","type":"uint256"}],"name":"GuardFailed","type":"error"},{"inputs":[],"name":"GuardsAlreadyInitialized","type":"error"},{"inputs":[],"name":"IncompleteGuardDefinition","type":"error"},{"inputs":[],"name":"InvalidArrayLength","type":"error"},{"inputs":[{"internalType":"uint256","name":"paramType","type":"uint256"}],"name":"InvalidGuardParamType","type":"error"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"MissingRole","type":"error"},{"inputs":[],"name":"TooManyGuards","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"smartVault","type":"address"},{"components":[{"internalType":"string","name":"methodSignature","type":"string"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bytes2","name":"operator","type":"bytes2"},{"internalType":"uint256","name":"expectedValue","type":"uint256"},{"internalType":"enum GuardParamType[]","name":"methodParamTypes","type":"uint8[]"},{"internalType":"bytes[]","name":"methodParamValues","type":"bytes[]"}],"indexed":false,"internalType":"struct GuardDefinition[][]","name":"guards","type":"tuple[][]"},{"indexed":false,"internalType":"enum RequestType[]","name":"requestTypes","type":"uint8[]"}],"name":"GuardsInitialized","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"guardsInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"smartVaultId","type":"address"},{"internalType":"enum RequestType","name":"requestType","type":"uint8"}],"name":"readGuards","outputs":[{"components":[{"internalType":"string","name":"methodSignature","type":"string"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bytes2","name":"operator","type":"bytes2"},{"internalType":"uint256","name":"expectedValue","type":"uint256"},{"internalType":"enum GuardParamType[]","name":"methodParamTypes","type":"uint8[]"},{"internalType":"bytes[]","name":"methodParamValues","type":"bytes[]"}],"internalType":"struct GuardDefinition[]","name":"guards","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"smartVaultId","type":"address"},{"components":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"executor","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"enum RequestType","name":"requestType","type":"uint8"},{"internalType":"uint256[]","name":"assets","type":"uint256[]"},{"internalType":"address[]","name":"tokens","type":"address[]"}],"internalType":"struct RequestContext","name":"context","type":"tuple"}],"name":"runGuards","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"smartVaultId","type":"address"},{"components":[{"internalType":"string","name":"methodSignature","type":"string"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bytes2","name":"operator","type":"bytes2"},{"internalType":"uint256","name":"expectedValue","type":"uint256"},{"internalType":"enum GuardParamType[]","name":"methodParamTypes","type":"uint8[]"},{"internalType":"bytes[]","name":"methodParamValues","type":"bytes[]"}],"internalType":"struct GuardDefinition[][]","name":"guards","type":"tuple[][]"},{"internalType":"enum RequestType[]","name":"requestTypes","type":"uint8[]"}],"name":"setGuards","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a06040523480156200001157600080fd5b506040516200286b3803806200286b833981016040819052620000349162000070565b806001600160a01b0381166200005d5760405163bb0e4c3560e01b815260040160405180910390fd5b6001600160a01b031660805250620000a2565b6000602082840312156200008357600080fd5b81516001600160a01b03811681146200009b57600080fd5b9392505050565b6080516127ad620000be600039600061116401526127ad6000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80632c8dfb26146100515780633993059014610066578063519fe8f614610079578063eaecd3c8146100a2575b600080fd5b61006461005f366004611620565b6100d5565b005b6100646100743660046116c3565b6102ef565b61008c610087366004611755565b610462565b6040516100999190611897565b60405180910390f35b6100c56100b03660046119dc565b60316020526000908152604090205460ff1681565b6040519015158152602001610099565b73ffffffffffffffffffffffffffffffffffffffff821660009081526032602052604081208161010b60808501606086016119f9565b600481111561011c5761011c6117f8565b600481111561012d5761012d6117f8565b815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff160361015d575050565b60006101788361017360808501606086016119f9565b610477565b905060005b81518110156102e957600082828151811061019a5761019a611a14565b602002602001015190506101de816020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163b151590565b6102375760208101516040517f247e970100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024015b60405180910390fd5b600061024c868361024788611bdd565b610628565b9050600080836020015173ffffffffffffffffffffffffffffffffffffffff168360405161027a9190611c8e565b600060405180830381855afa9150503d80600081146102b5576040519150601f19603f3d011682016040523d82523d6000602084013e6102ba565b606091505b50915091506102d482828660400151876060015189610e86565b50505050806102e290611cd9565b905061017d565b50505050565b7fadcdbe1f109205bda263b8a003b032ba3d5feba6ed7a93446d414c5591a927103361031b8282611118565b61032487611228565b84831461035d576040517f9d89020a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b838110156103cc576103bc8886868481811061037e5761037e611a14565b905060200201602081019061039391906119f9565b8989858181106103a5576103a5611a14565b90506020028101906103b79190611d11565b61128b565b6103c581611cd9565b9050610360565b5073ffffffffffffffffffffffffffffffffffffffff87166000818152603160205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517fb9f47a76b7534856ef0c4c98da9b5c95949f67ee9394a455848de9e081c42ee4906104519089908990899089906120b0565b60405180910390a250505050505050565b606061046e8383610477565b90505b92915050565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260326020526040812060609190818460048111156104b3576104b36117f8565b60048111156104c4576104c46117f8565b815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff1603610591576040805160008082526020820190925290610589565b6105766040518060c0016040528060608152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160007dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020016000815260200160608152602001606081525090565b8152602001906001900390816105065790505b509050610471565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260326020526040812061060a90828560048111156105cd576105cd6117f8565b60048111156105de576105de6117f8565b815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff166114a7565b905080806020019051810190610620919061231f565b949350505050565b6060600083600001516040516020016106419190611c8e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120608088015151600085529184018352935091906106999082908590820161249f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905290506000806106d78460206124e6565b905060005b84811015610b36576000896080015182815181106106fc576106fc611a14565b60200260200101519050600880811115610718576107186117f8565b81600881111561072a5761072a6117f8565b036107dd57848360405160200161074391815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261077f92916020016124fd565b60405160208183030381529060405294508960a001518461ffff16815181106107aa576107aa611a14565b60200260200101515160206107bf919061252c565b6107c9908461252c565b9250836107d58161253f565b945050610b25565b60078160088111156107f1576107f16117f8565b0361084657848a60a001518561ffff168151811061081157610811611a14565b602002602001015160405160200161082a9291906124fd565b604051602081830303815290604052945083806107d59061253f565b600081600881111561085a5761085a6117f8565b036108d5576040805173ffffffffffffffffffffffffffffffffffffffff8d1660208201528691015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526108bf92916020016124fd565b6040516020818303038152906040529450610b25565b60028160088111156108e9576108e96117f8565b036109195788516040805173ffffffffffffffffffffffffffffffffffffffff9092166020830152869101610883565b600181600881111561092d5761092d6117f8565b0361096457848960200151604051602001610883919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6003816008811115610978576109786117f8565b036109aa576040808a0151815173ffffffffffffffffffffffffffffffffffffffff9091166020820152869101610883565b60048160088111156109be576109be6117f8565b03610a525784836040516020016109d791815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052610a1392916020016124fd565b60405160208183030381529060405294508860800151516020610a3691906124e6565b610a4190602061252c565b610a4b908461252c565b9250610b25565b6005816008811115610a6657610a666117f8565b03610ade578483604051602001610a7f91815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052610abb92916020016124fd565b60405160208183030381529060405294508860a00151516020610a3691906124e6565b806008811115610af057610af06117f8565b6040517ffab34f5200000000000000000000000000000000000000000000000000000000815260040161022e91815260200190565b50610b2f81611cd9565b90506106dc565b506000915060005b84811015610e7657600089608001518281518110610b5e57610b5e611a14565b60200260200101519050600880811115610b7a57610b7a6117f8565b816008811115610b8c57610b8c6117f8565b03610c78578460208b60a001518661ffff1681518110610bae57610bae611a14565b602002602001015151610bc19190612560565b604051602001610bd391815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052610c0f92916020016124fd565b6040516020818303038152906040529450848a60a001518561ffff1681518110610c3b57610c3b611a14565b6020026020010151604051602001610c549291906124fd565b60405160208183030381529060405294508380610c709061253f565b945050610e65565b6007816008811115610c8c57610c8c6117f8565b03610c9b5783610c708161253f565b6004816008811115610caf57610caf6117f8565b03610d825784896080015151604051602001610ccd91815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052610d0992916020016124fd565b6040516020818303038152906040529450848960800151604051602001610d30919061259b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052610d6c92916020016124fd565b6040516020818303038152906040529450610e65565b6005816008811115610d9657610d966117f8565b03610e6557848960a0015151604051602001610db491815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052610df092916020016124fd565b6040516020818303038152906040529450848960a00151604051602001610e1791906125d1565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052610e5392916020016124fd565b60405160208183030381529060405294505b50610e6f81611cd9565b9050610b3e565b50919450505050505b9392505050565b84610ebd576040517fb6a383fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60017fc2c30000000000000000000000000000000000000000000000000000000000007fffff000000000000000000000000000000000000000000000000000000000000851601610f25578285806020019051810190610f1d9190612611565b1490506110d6565b7fc3c30000000000000000000000000000000000000000000000000000000000007fffff000000000000000000000000000000000000000000000000000000000000851601610f8c578285806020019051810190610f839190612611565b111590506110d6565b7fc1c30000000000000000000000000000000000000000000000000000000000007fffff000000000000000000000000000000000000000000000000000000000000851601610ff3578285806020019051810190610fea9190612611565b101590506110d6565b7fc4000000000000000000000000000000000000000000000000000000000000007fffff0000000000000000000000000000000000000000000000000000000000008516016110595782858060200190518101906110519190612611565b1090506110d6565b7fc2000000000000000000000000000000000000000000000000000000000000007fffff0000000000000000000000000000000000000000000000000000000000008516016110bf5782858060200190518101906110b79190612611565b1190506110d6565b848060200190518101906110d3919061262a565b90505b80611110576040517fd246c8d70000000000000000000000000000000000000000000000000000000081526004810183905260240161022e565b505050505050565b6040517f91d148540000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff82811660248301527f000000000000000000000000000000000000000000000000000000000000000016906391d1485490604401602060405180830381865afa1580156111ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111cf919061262a565b611224576040517f75000dc00000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff8216602482015260440161022e565b5050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526031602052604090205460ff1615611288576040517fcf0b7d4e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b60008190036112c6576040517ff63ee30500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a811115611301576040517fcd084cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b818110156113d957600083838381811061132057611320611a14565b9050602002810190611332919061264c565b6113439060408101906020016119dc565b73ffffffffffffffffffffffffffffffffffffffff161480611392575082828281811061137257611372611a14565b9050602002810190611384919061264c565b61138e9080612680565b1590505b156113c9576040517ff63ee30500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113d281611cd9565b9050611304565b50600061140683836040516020016113f29291906126e5565b6040516020818303038152906040526114d5565b73ffffffffffffffffffffffffffffffffffffffff86166000908152603260205260408120919250829190866004811115611443576114436117f8565b6004811115611454576114546117f8565b815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b60606104718260016114d08173ffffffffffffffffffffffffffffffffffffffff84163b6126f9565b6115ad565b600080826040516020016114e9919061270c565b604051602081830303815290604052905060008160405160200161150d9190612732565b60405160208183030381529060405290508051602082016000f0925073ffffffffffffffffffffffffffffffffffffffff83166115a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4445504c4f594d454e545f4641494c4544000000000000000000000000000000604482015260640161022e565b5050919050565b60408051603f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168101909152818152818360208301863c9392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461128857600080fd5b803561161b816115ee565b919050565b6000806040838503121561163357600080fd5b823561163e816115ee565b9150602083013567ffffffffffffffff81111561165a57600080fd5b830160c0818603121561166c57600080fd5b809150509250929050565b60008083601f84011261168957600080fd5b50813567ffffffffffffffff8111156116a157600080fd5b6020830191508360208260051b85010111156116bc57600080fd5b9250929050565b6000806000806000606086880312156116db57600080fd5b85356116e6816115ee565b9450602086013567ffffffffffffffff8082111561170357600080fd5b61170f89838a01611677565b9096509450604088013591508082111561172857600080fd5b5061173588828901611677565b969995985093965092949392505050565b80356005811061161b57600080fd5b6000806040838503121561176857600080fd5b8235611773816115ee565b915061178160208401611746565b90509250929050565b60005b838110156117a557818101518382015260200161178d565b50506000910152565b600081518084526117c681602086016020860161178a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600060098210611839576118396117f8565b50815260200190565b600081518084526020808501808196508360051b8101915082860160005b8581101561188a5782840389526118788483516117ae565b98850198935090840190600101611860565b5091979650505050505050565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b848110156119cd577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08a8503018652825160c08151818752611903828801826117ae565b838c015173ffffffffffffffffffffffffffffffffffffffff16888d01528a8401517fffff000000000000000000000000000000000000000000000000000000000000168b89015260608085015190890152608080850151898303918a01919091528051808352908d019350908c01915085905b8082101561199c5761198a838551611827565b92508c84019350600182019150611977565b505060a092830151878203888501529291506119b88184611842565b988b01989650505092880192506001016118bf565b50919998505050505050505050565b6000602082840312156119ee57600080fd5b8135610e7f816115ee565b600060208284031215611a0b57600080fd5b61046e82611746565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715611a9557611a95611a43565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611ae257611ae2611a43565b604052919050565b600067ffffffffffffffff821115611b0457611b04611a43565b5060051b60200190565b600082601f830112611b1f57600080fd5b81356020611b34611b2f83611aea565b611a9b565b82815260059290921b84018101918181019086841115611b5357600080fd5b8286015b84811015611b6e5780358352918301918301611b57565b509695505050505050565b600082601f830112611b8a57600080fd5b81356020611b9a611b2f83611aea565b82815260059290921b84018101918181019086841115611bb957600080fd5b8286015b84811015611b6e578035611bd0816115ee565b8352918301918301611bbd565b600060c08236031215611bef57600080fd5b611bf7611a72565b611c0083611610565b8152611c0e60208401611610565b6020820152611c1f60408401611610565b6040820152611c3060608401611746565b6060820152608083013567ffffffffffffffff80821115611c5057600080fd5b611c5c36838701611b0e565b608084015260a0850135915080821115611c7557600080fd5b50611c8236828601611b79565b60a08301525092915050565b60008251611ca081846020870161178a565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611d0a57611d0a611caa565b5060010190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611d4657600080fd5b83018035915067ffffffffffffffff821115611d6157600080fd5b6020019150600581901b36038213156116bc57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611dae57600080fd5b830160208101925035905067ffffffffffffffff811115611dce57600080fd5b8036038213156116bc57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b7fffff0000000000000000000000000000000000000000000000000000000000008116811461128857600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611e8957600080fd5b830160208101925035905067ffffffffffffffff811115611ea957600080fd5b8060051b36038213156116bc57600080fd5b6009811061128857600080fd5b8183526000602080850194508260005b85811015611f04578135611eeb81611ebb565b611ef58882611827565b97505090820190600101611ed8565b509495945050505050565b81835260006020808501808196508560051b810191508460005b8781101561188a578284038952611f408288611d79565b611f4b868284611ddd565b9a87019a9550505090840190600101611f29565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41833603018112611f9357600080fd5b90910192915050565b81835260006020808501808196508560051b810191508460005b8781101561188a578284038952611fcd8288611f5f565b60c0611fd98283611d79565b828852611fe98389018284611ddd565b9250505086820135611ffa816115ee565b73ffffffffffffffffffffffffffffffffffffffff168688015260408281013561202381611e26565b7fffff000000000000000000000000000000000000000000000000000000000000169087015260608281013590870152608061206181840184611e54565b888403838a0152612073848284611ec8565b935050505060a061208681840184611e54565b93508783038289015261209a838583611f0f565b9c89019c97505050928601925050600101611fb6565b604080825281018490526000600560608084019087831b85010188845b89811015612129577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0878403018452612106828c611e54565b612111858284611f9c565b602096870196909550939093019250506001016120cd565b505084810360208681019190915286825291508690820160005b878110156121755761215483611746565b858110612163576121636117f8565b82529183019190830190600101612143565b509998505050505050505050565b600067ffffffffffffffff83111561219d5761219d611a43565b6121ce60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f86011601611a9b565b90508281528383830111156121e257600080fd5b610e7f83602083018461178a565b600082601f83011261220157600080fd5b61046e83835160208501612183565b805161161b816115ee565b805161161b81611e26565b600082601f83011261223757600080fd5b81516020612247611b2f83611aea565b82815260059290921b8401810191818101908684111561226657600080fd5b8286015b84811015611b6e57805161227d81611ebb565b835291830191830161226a565b600082601f83011261229b57600080fd5b815160206122ab611b2f83611aea565b82815260059290921b840181019181810190868411156122ca57600080fd5b8286015b84811015611b6e57805167ffffffffffffffff8111156122ee5760008081fd5b8701603f810189136123005760008081fd5b612311898683015160408401612183565b8452509183019183016122ce565b6000602080838503121561233257600080fd5b825167ffffffffffffffff8082111561234a57600080fd5b818501915085601f83011261235e57600080fd5b815161236c611b2f82611aea565b81815260059190911b8301840190848101908883111561238b57600080fd5b8585015b83811015612492578051858111156123a657600080fd5b860160c0818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00112156123db5760008081fd5b6123e3611a72565b88820151878111156123f55760008081fd5b6124038d8b838601016121f0565b8252506040612413818401612210565b8a830152606061242481850161221b565b828401526080915081840151818401525060a080840151898111156124495760008081fd5b6124578f8d83880101612226565b838501525060c08401519150888211156124715760008081fd5b61247f8e8c8487010161228a565b908301525084525091860191860161238f565b5098975050505050505050565b600083516124b181846020880161178a565b7fffffffff00000000000000000000000000000000000000000000000000000000939093169190920190815260040192915050565b808202811582820484141761047157610471611caa565b6000835161250f81846020880161178a565b83519083019061252381836020880161178a565b01949350505050565b8082018082111561047157610471611caa565b600061ffff80831681810361255657612556611caa565b6001019392505050565b600082612596577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b815160009082906020808601845b838110156125c5578151855293820193908201906001016125a9565b50929695505050505050565b815160009082906020808601845b838110156125c557815173ffffffffffffffffffffffffffffffffffffffff16855293820193908201906001016125df565b60006020828403121561262357600080fd5b5051919050565b60006020828403121561263c57600080fd5b81518015158114610e7f57600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41833603018112611ca057600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126126b557600080fd5b83018035915067ffffffffffffffff8211156126d057600080fd5b6020019150368190038213156116bc57600080fd5b602081526000610620602083018486611f9c565b8181038181111561047157610471611caa565b600081526000825161272581600185016020870161178a565b9190910160010192915050565b7f600b5981380380925939f300000000000000000000000000000000000000000081526000825161276a81600b85016020870161178a565b91909101600b019291505056fea2646970667358221220b21f56390d61be0c960d01ffc45b0d3c724866f1cabb0fbbebb3937333a13d0164736f6c634300081100330000000000000000000000007b533e72e0cdc63aacd8cdb926ac402b846fbd13
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80632c8dfb26146100515780633993059014610066578063519fe8f614610079578063eaecd3c8146100a2575b600080fd5b61006461005f366004611620565b6100d5565b005b6100646100743660046116c3565b6102ef565b61008c610087366004611755565b610462565b6040516100999190611897565b60405180910390f35b6100c56100b03660046119dc565b60316020526000908152604090205460ff1681565b6040519015158152602001610099565b73ffffffffffffffffffffffffffffffffffffffff821660009081526032602052604081208161010b60808501606086016119f9565b600481111561011c5761011c6117f8565b600481111561012d5761012d6117f8565b815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff160361015d575050565b60006101788361017360808501606086016119f9565b610477565b905060005b81518110156102e957600082828151811061019a5761019a611a14565b602002602001015190506101de816020015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163b151590565b6102375760208101516040517f247e970100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024015b60405180910390fd5b600061024c868361024788611bdd565b610628565b9050600080836020015173ffffffffffffffffffffffffffffffffffffffff168360405161027a9190611c8e565b600060405180830381855afa9150503d80600081146102b5576040519150601f19603f3d011682016040523d82523d6000602084013e6102ba565b606091505b50915091506102d482828660400151876060015189610e86565b50505050806102e290611cd9565b905061017d565b50505050565b7fadcdbe1f109205bda263b8a003b032ba3d5feba6ed7a93446d414c5591a927103361031b8282611118565b61032487611228565b84831461035d576040517f9d89020a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b838110156103cc576103bc8886868481811061037e5761037e611a14565b905060200201602081019061039391906119f9565b8989858181106103a5576103a5611a14565b90506020028101906103b79190611d11565b61128b565b6103c581611cd9565b9050610360565b5073ffffffffffffffffffffffffffffffffffffffff87166000818152603160205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517fb9f47a76b7534856ef0c4c98da9b5c95949f67ee9394a455848de9e081c42ee4906104519089908990899089906120b0565b60405180910390a250505050505050565b606061046e8383610477565b90505b92915050565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260326020526040812060609190818460048111156104b3576104b36117f8565b60048111156104c4576104c46117f8565b815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff1603610591576040805160008082526020820190925290610589565b6105766040518060c0016040528060608152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160007dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020016000815260200160608152602001606081525090565b8152602001906001900390816105065790505b509050610471565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260326020526040812061060a90828560048111156105cd576105cd6117f8565b60048111156105de576105de6117f8565b815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff166114a7565b905080806020019051810190610620919061231f565b949350505050565b6060600083600001516040516020016106419190611c8e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120608088015151600085529184018352935091906106999082908590820161249f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905290506000806106d78460206124e6565b905060005b84811015610b36576000896080015182815181106106fc576106fc611a14565b60200260200101519050600880811115610718576107186117f8565b81600881111561072a5761072a6117f8565b036107dd57848360405160200161074391815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261077f92916020016124fd565b60405160208183030381529060405294508960a001518461ffff16815181106107aa576107aa611a14565b60200260200101515160206107bf919061252c565b6107c9908461252c565b9250836107d58161253f565b945050610b25565b60078160088111156107f1576107f16117f8565b0361084657848a60a001518561ffff168151811061081157610811611a14565b602002602001015160405160200161082a9291906124fd565b604051602081830303815290604052945083806107d59061253f565b600081600881111561085a5761085a6117f8565b036108d5576040805173ffffffffffffffffffffffffffffffffffffffff8d1660208201528691015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526108bf92916020016124fd565b6040516020818303038152906040529450610b25565b60028160088111156108e9576108e96117f8565b036109195788516040805173ffffffffffffffffffffffffffffffffffffffff9092166020830152869101610883565b600181600881111561092d5761092d6117f8565b0361096457848960200151604051602001610883919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6003816008811115610978576109786117f8565b036109aa576040808a0151815173ffffffffffffffffffffffffffffffffffffffff9091166020820152869101610883565b60048160088111156109be576109be6117f8565b03610a525784836040516020016109d791815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052610a1392916020016124fd565b60405160208183030381529060405294508860800151516020610a3691906124e6565b610a4190602061252c565b610a4b908461252c565b9250610b25565b6005816008811115610a6657610a666117f8565b03610ade578483604051602001610a7f91815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052610abb92916020016124fd565b60405160208183030381529060405294508860a00151516020610a3691906124e6565b806008811115610af057610af06117f8565b6040517ffab34f5200000000000000000000000000000000000000000000000000000000815260040161022e91815260200190565b50610b2f81611cd9565b90506106dc565b506000915060005b84811015610e7657600089608001518281518110610b5e57610b5e611a14565b60200260200101519050600880811115610b7a57610b7a6117f8565b816008811115610b8c57610b8c6117f8565b03610c78578460208b60a001518661ffff1681518110610bae57610bae611a14565b602002602001015151610bc19190612560565b604051602001610bd391815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052610c0f92916020016124fd565b6040516020818303038152906040529450848a60a001518561ffff1681518110610c3b57610c3b611a14565b6020026020010151604051602001610c549291906124fd565b60405160208183030381529060405294508380610c709061253f565b945050610e65565b6007816008811115610c8c57610c8c6117f8565b03610c9b5783610c708161253f565b6004816008811115610caf57610caf6117f8565b03610d825784896080015151604051602001610ccd91815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052610d0992916020016124fd565b6040516020818303038152906040529450848960800151604051602001610d30919061259b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052610d6c92916020016124fd565b6040516020818303038152906040529450610e65565b6005816008811115610d9657610d966117f8565b03610e6557848960a0015151604051602001610db491815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052610df092916020016124fd565b6040516020818303038152906040529450848960a00151604051602001610e1791906125d1565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052610e5392916020016124fd565b60405160208183030381529060405294505b50610e6f81611cd9565b9050610b3e565b50919450505050505b9392505050565b84610ebd576040517fb6a383fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60017fc2c30000000000000000000000000000000000000000000000000000000000007fffff000000000000000000000000000000000000000000000000000000000000851601610f25578285806020019051810190610f1d9190612611565b1490506110d6565b7fc3c30000000000000000000000000000000000000000000000000000000000007fffff000000000000000000000000000000000000000000000000000000000000851601610f8c578285806020019051810190610f839190612611565b111590506110d6565b7fc1c30000000000000000000000000000000000000000000000000000000000007fffff000000000000000000000000000000000000000000000000000000000000851601610ff3578285806020019051810190610fea9190612611565b101590506110d6565b7fc4000000000000000000000000000000000000000000000000000000000000007fffff0000000000000000000000000000000000000000000000000000000000008516016110595782858060200190518101906110519190612611565b1090506110d6565b7fc2000000000000000000000000000000000000000000000000000000000000007fffff0000000000000000000000000000000000000000000000000000000000008516016110bf5782858060200190518101906110b79190612611565b1190506110d6565b848060200190518101906110d3919061262a565b90505b80611110576040517fd246c8d70000000000000000000000000000000000000000000000000000000081526004810183905260240161022e565b505050505050565b6040517f91d148540000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff82811660248301527f0000000000000000000000007b533e72e0cdc63aacd8cdb926ac402b846fbd1316906391d1485490604401602060405180830381865afa1580156111ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111cf919061262a565b611224576040517f75000dc00000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff8216602482015260440161022e565b5050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526031602052604090205460ff1615611288576040517fcf0b7d4e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b60008190036112c6576040517ff63ee30500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a811115611301576040517fcd084cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b818110156113d957600083838381811061132057611320611a14565b9050602002810190611332919061264c565b6113439060408101906020016119dc565b73ffffffffffffffffffffffffffffffffffffffff161480611392575082828281811061137257611372611a14565b9050602002810190611384919061264c565b61138e9080612680565b1590505b156113c9576040517ff63ee30500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113d281611cd9565b9050611304565b50600061140683836040516020016113f29291906126e5565b6040516020818303038152906040526114d5565b73ffffffffffffffffffffffffffffffffffffffff86166000908152603260205260408120919250829190866004811115611443576114436117f8565b6004811115611454576114546117f8565b815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b60606104718260016114d08173ffffffffffffffffffffffffffffffffffffffff84163b6126f9565b6115ad565b600080826040516020016114e9919061270c565b604051602081830303815290604052905060008160405160200161150d9190612732565b60405160208183030381529060405290508051602082016000f0925073ffffffffffffffffffffffffffffffffffffffff83166115a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4445504c4f594d454e545f4641494c4544000000000000000000000000000000604482015260640161022e565b5050919050565b60408051603f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168101909152818152818360208301863c9392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461128857600080fd5b803561161b816115ee565b919050565b6000806040838503121561163357600080fd5b823561163e816115ee565b9150602083013567ffffffffffffffff81111561165a57600080fd5b830160c0818603121561166c57600080fd5b809150509250929050565b60008083601f84011261168957600080fd5b50813567ffffffffffffffff8111156116a157600080fd5b6020830191508360208260051b85010111156116bc57600080fd5b9250929050565b6000806000806000606086880312156116db57600080fd5b85356116e6816115ee565b9450602086013567ffffffffffffffff8082111561170357600080fd5b61170f89838a01611677565b9096509450604088013591508082111561172857600080fd5b5061173588828901611677565b969995985093965092949392505050565b80356005811061161b57600080fd5b6000806040838503121561176857600080fd5b8235611773816115ee565b915061178160208401611746565b90509250929050565b60005b838110156117a557818101518382015260200161178d565b50506000910152565b600081518084526117c681602086016020860161178a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600060098210611839576118396117f8565b50815260200190565b600081518084526020808501808196508360051b8101915082860160005b8581101561188a5782840389526118788483516117ae565b98850198935090840190600101611860565b5091979650505050505050565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b848110156119cd577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08a8503018652825160c08151818752611903828801826117ae565b838c015173ffffffffffffffffffffffffffffffffffffffff16888d01528a8401517fffff000000000000000000000000000000000000000000000000000000000000168b89015260608085015190890152608080850151898303918a01919091528051808352908d019350908c01915085905b8082101561199c5761198a838551611827565b92508c84019350600182019150611977565b505060a092830151878203888501529291506119b88184611842565b988b01989650505092880192506001016118bf565b50919998505050505050505050565b6000602082840312156119ee57600080fd5b8135610e7f816115ee565b600060208284031215611a0b57600080fd5b61046e82611746565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715611a9557611a95611a43565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611ae257611ae2611a43565b604052919050565b600067ffffffffffffffff821115611b0457611b04611a43565b5060051b60200190565b600082601f830112611b1f57600080fd5b81356020611b34611b2f83611aea565b611a9b565b82815260059290921b84018101918181019086841115611b5357600080fd5b8286015b84811015611b6e5780358352918301918301611b57565b509695505050505050565b600082601f830112611b8a57600080fd5b81356020611b9a611b2f83611aea565b82815260059290921b84018101918181019086841115611bb957600080fd5b8286015b84811015611b6e578035611bd0816115ee565b8352918301918301611bbd565b600060c08236031215611bef57600080fd5b611bf7611a72565b611c0083611610565b8152611c0e60208401611610565b6020820152611c1f60408401611610565b6040820152611c3060608401611746565b6060820152608083013567ffffffffffffffff80821115611c5057600080fd5b611c5c36838701611b0e565b608084015260a0850135915080821115611c7557600080fd5b50611c8236828601611b79565b60a08301525092915050565b60008251611ca081846020870161178a565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611d0a57611d0a611caa565b5060010190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611d4657600080fd5b83018035915067ffffffffffffffff821115611d6157600080fd5b6020019150600581901b36038213156116bc57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611dae57600080fd5b830160208101925035905067ffffffffffffffff811115611dce57600080fd5b8036038213156116bc57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b7fffff0000000000000000000000000000000000000000000000000000000000008116811461128857600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611e8957600080fd5b830160208101925035905067ffffffffffffffff811115611ea957600080fd5b8060051b36038213156116bc57600080fd5b6009811061128857600080fd5b8183526000602080850194508260005b85811015611f04578135611eeb81611ebb565b611ef58882611827565b97505090820190600101611ed8565b509495945050505050565b81835260006020808501808196508560051b810191508460005b8781101561188a578284038952611f408288611d79565b611f4b868284611ddd565b9a87019a9550505090840190600101611f29565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41833603018112611f9357600080fd5b90910192915050565b81835260006020808501808196508560051b810191508460005b8781101561188a578284038952611fcd8288611f5f565b60c0611fd98283611d79565b828852611fe98389018284611ddd565b9250505086820135611ffa816115ee565b73ffffffffffffffffffffffffffffffffffffffff168688015260408281013561202381611e26565b7fffff000000000000000000000000000000000000000000000000000000000000169087015260608281013590870152608061206181840184611e54565b888403838a0152612073848284611ec8565b935050505060a061208681840184611e54565b93508783038289015261209a838583611f0f565b9c89019c97505050928601925050600101611fb6565b604080825281018490526000600560608084019087831b85010188845b89811015612129577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0878403018452612106828c611e54565b612111858284611f9c565b602096870196909550939093019250506001016120cd565b505084810360208681019190915286825291508690820160005b878110156121755761215483611746565b858110612163576121636117f8565b82529183019190830190600101612143565b509998505050505050505050565b600067ffffffffffffffff83111561219d5761219d611a43565b6121ce60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f86011601611a9b565b90508281528383830111156121e257600080fd5b610e7f83602083018461178a565b600082601f83011261220157600080fd5b61046e83835160208501612183565b805161161b816115ee565b805161161b81611e26565b600082601f83011261223757600080fd5b81516020612247611b2f83611aea565b82815260059290921b8401810191818101908684111561226657600080fd5b8286015b84811015611b6e57805161227d81611ebb565b835291830191830161226a565b600082601f83011261229b57600080fd5b815160206122ab611b2f83611aea565b82815260059290921b840181019181810190868411156122ca57600080fd5b8286015b84811015611b6e57805167ffffffffffffffff8111156122ee5760008081fd5b8701603f810189136123005760008081fd5b612311898683015160408401612183565b8452509183019183016122ce565b6000602080838503121561233257600080fd5b825167ffffffffffffffff8082111561234a57600080fd5b818501915085601f83011261235e57600080fd5b815161236c611b2f82611aea565b81815260059190911b8301840190848101908883111561238b57600080fd5b8585015b83811015612492578051858111156123a657600080fd5b860160c0818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00112156123db5760008081fd5b6123e3611a72565b88820151878111156123f55760008081fd5b6124038d8b838601016121f0565b8252506040612413818401612210565b8a830152606061242481850161221b565b828401526080915081840151818401525060a080840151898111156124495760008081fd5b6124578f8d83880101612226565b838501525060c08401519150888211156124715760008081fd5b61247f8e8c8487010161228a565b908301525084525091860191860161238f565b5098975050505050505050565b600083516124b181846020880161178a565b7fffffffff00000000000000000000000000000000000000000000000000000000939093169190920190815260040192915050565b808202811582820484141761047157610471611caa565b6000835161250f81846020880161178a565b83519083019061252381836020880161178a565b01949350505050565b8082018082111561047157610471611caa565b600061ffff80831681810361255657612556611caa565b6001019392505050565b600082612596577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b815160009082906020808601845b838110156125c5578151855293820193908201906001016125a9565b50929695505050505050565b815160009082906020808601845b838110156125c557815173ffffffffffffffffffffffffffffffffffffffff16855293820193908201906001016125df565b60006020828403121561262357600080fd5b5051919050565b60006020828403121561263c57600080fd5b81518015158114610e7f57600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41833603018112611ca057600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126126b557600080fd5b83018035915067ffffffffffffffff8211156126d057600080fd5b6020019150368190038213156116bc57600080fd5b602081526000610620602083018486611f9c565b8181038181111561047157610471611caa565b600081526000825161272581600185016020870161178a565b9190910160010192915050565b7f600b5981380380925939f300000000000000000000000000000000000000000081526000825161276a81600b85016020870161178a565b91909101600b019291505056fea2646970667358221220b21f56390d61be0c960d01ffc45b0d3c724866f1cabb0fbbebb3937333a13d0164736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000007b533e72e0cdc63aacd8cdb926ac402b846fbd13
-----Decoded View---------------
Arg [0] : accessControl (address): 0x7b533e72E0cDC63AacD8cDB926AC402b846Fbd13
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000007b533e72e0cdc63aacd8cdb926ac402b846fbd13
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.