Feature Tip: Add private address tag to any address under My Name Tag !
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 65 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Execute Instruct... | 15681879 | 836 days ago | IN | 0 ETH | 0.00122572 | ||||
Deposit | 15675551 | 837 days ago | IN | 0 ETH | 0.00246202 | ||||
Deposit | 15675551 | 837 days ago | IN | 0.0001 ETH | 0.00168925 | ||||
Register Settlem... | 15675522 | 837 days ago | IN | 0 ETH | 0.00425633 | ||||
Execute Instruct... | 15670247 | 838 days ago | IN | 0 ETH | 0.00168418 | ||||
Deposit | 15670207 | 838 days ago | IN | 0.0001 ETH | 0.00157806 | ||||
Deposit | 15670188 | 838 days ago | IN | 0 ETH | 0.00215477 | ||||
Register Settlem... | 15670148 | 838 days ago | IN | 0 ETH | 0.00436952 | ||||
Register Settlem... | 15590490 | 849 days ago | IN | 0 ETH | 0.01049948 | ||||
Register Settlem... | 15409959 | 877 days ago | IN | 0 ETH | 0.00583559 | ||||
Register Settlem... | 15380650 | 882 days ago | IN | 0 ETH | 0.00108861 | ||||
Register Settlem... | 15373519 | 883 days ago | IN | 0 ETH | 0.00795661 | ||||
Register Settlem... | 15373492 | 883 days ago | IN | 0 ETH | 0.02432067 | ||||
Register Settlem... | 15371665 | 883 days ago | IN | 0 ETH | 0.00481846 | ||||
Register Settlem... | 15371651 | 883 days ago | IN | 0 ETH | 0.00448502 | ||||
Deposit | 15371622 | 883 days ago | IN | 0 ETH | 0.00162966 | ||||
Register Settlem... | 15371392 | 883 days ago | IN | 0 ETH | 0.00810629 | ||||
Register Settlem... | 15371372 | 883 days ago | IN | 0 ETH | 0.00518889 | ||||
Deposit | 15366630 | 884 days ago | IN | 0.0001 ETH | 0.0012037 | ||||
Deposit | 15366139 | 884 days ago | IN | 0.0001 ETH | 0.00172405 | ||||
Register Settlem... | 15365951 | 884 days ago | IN | 0 ETH | 0.00752995 | ||||
Deposit | 15365859 | 884 days ago | IN | 0.0001 ETH | 0.00163605 | ||||
Deposit | 15360703 | 885 days ago | IN | 0 ETH | 0.00225266 | ||||
Register Settlem... | 15360681 | 885 days ago | IN | 0 ETH | 0.00645484 | ||||
Deposit | 15360282 | 885 days ago | IN | 0 ETH | 0.0049141 |
Latest 8 internal transactions
Advanced mode:
Loading...
Loading
Contract Name:
MSSC
Compiler Version
v0.8.4+commit.c7e474f2
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
//SPDX-License-Identifier: Unlicense pragma solidity ^0.8.0; import "@openzeppelin/contracts/access/AccessControl.sol"; import "./lib/SSCVault.sol"; import "./lib/Assertions.sol"; contract MSSC is SSCVault, AccessControl { // Events event RegisterCycle(bytes32 indexed cycleId, Instruction[] instructions); event ExecuteCycle(bytes32 indexed cycleId, bytes32[] instructions); bytes32 public constant MEMBRANE_ROLE = keccak256("MEMBRANE"); mapping(bytes32 => SettlementCycle) private _cycles; mapping(bytes32 => Instruction) private _instructions; constructor() payable { _grantRole(DEFAULT_ADMIN_ROLE, _msgSender()); _grantRole(MEMBRANE_ROLE, _msgSender()); } /** * @notice Register settlementCycle, this function can only be perfomed by a Membrane wallet. * Caller must transform obfuscatedId string to bytes32, pure strings are not supported. * * @param cycleId Cycle's bytes32 obfuscatedId to register. * @param instructions instructions to register. */ function registerSettlementCycle( bytes32 cycleId, Instruction[] calldata instructions ) external onlyRole(MEMBRANE_ROLE) { _assertCycleDoesNotExist(cycleId); // Retrieve the total number of instructions and place on the stack. uint256 totalInstructions = instructions.length; if (totalInstructions == 0) { revert CycleHasNoInstruction(); } bytes32[] storage newInstructions = _cycles[cycleId].instructions; for (uint256 i = 0; i < totalInstructions; ) { Instruction memory instruction = instructions[i]; bytes32 instructionId = instruction.id; _assertValidInstruction(instruction); newInstructions.push(instructionId); _instructions[instructionId] = instruction; // Skip overflow check as for loop is indexed starting at zero. unchecked { ++i; } } emit RegisterCycle(cycleId, instructions); } /** * @notice Execute instructions in a SettlementCycle, anyone can call this function as long as it * meets some requirements. * * @param cycleId Cycle's bytes32 obfuscatedId to execute. */ function executeInstructions(bytes32 cycleId) external { _assertCycleExists(cycleId); _assertCycleIsNotExecuted(cycleId); _cycles[cycleId].executed = true; bytes32[] memory instructions = _cycles[cycleId].instructions; // Retrieve the total number of instructions and place on the stack. uint256 totalInstructions = instructions.length; for (uint256 i = 0; i < totalInstructions; ) { Instruction memory instruction = _instructions[instructions[i]]; DepositItem memory depositItem = _buildDepositItem(instruction); _withdrawTo(depositItem, instruction.receiver); // Skip overflow check as for loop is indexed starting at zero. unchecked { ++i; } } emit ExecuteCycle(cycleId, instructions); } /** * @notice Make deposits (Native coin or ERC20 tokens) to a existent instruction, {msg.sender} will become * the {sender} of the instruction hence will be the only account which is able to withdraw * those allocated funds. * * @param instructionId Instruction to allocate funds. */ function deposit(bytes32 instructionId) external payable { Instruction memory instruction = _instructions[instructionId]; uint256 amount = instruction.amount; // Ensure that instruction does exist by checking its amount. if (amount == 0) { revert NoInstruction(instructionId); } DepositItem memory depositItem = _buildDepositItem(instruction); _deposit(depositItem, amount); } /** * @notice Withdraw funds from a settlement. Caller must be the sender of instruction. * * @param instructionId Instruction to withdraw deposited funds from. */ function withdraw(bytes32 instructionId) external { DepositItem memory depositItem = _buildDepositItem( _instructions[instructionId] ); _withdraw(depositItem); } /** * @notice View function to get the instructions ids in a settlement cycle. * * @param cycleId Cycle to check. */ function getSettlementInstructions(bytes32 cycleId) external view returns (bytes32[] memory) { _assertCycleExists(cycleId); return _cycles[cycleId].instructions; } /** * @notice View function to check if a cycle has been registered. * * @param cycleId Cycle to check. */ function registered(bytes32 cycleId) external view returns (bool) { return _exist(cycleId); } /** * @notice View function to check if a cycle has been executed. * * @param cycleId Cycle to check. */ function executed(bytes32 cycleId) external view returns (bool) { _assertCycleExists(cycleId); return _cycles[cycleId].executed; } /** * @notice View function to get deposited funds to an instruction. * * @param instructionId Instruction to get deposited funds from. */ function deposits(bytes32 instructionId) external view returns (uint256) { return _deposits[instructionId]; } /** * @notice View function to get sender of a instruction. * * @param instructionId Instruction to get the sender. */ function senderOf(bytes32 instructionId) external view returns (address) { return _senderOf[instructionId]; } /*////////////////////////////////////////////////////////////// ASSERTIONS //////////////////////////////////////////////////////////////*/ // Check if an address is a sender of any instruction in the instruction. // Ensure that {cycleId} is registered. function _assertCycleExists(bytes32 cycleId) private view { if (!_exist(cycleId)) { revert NoCycle(); } } // Ensure that {cycleId} is NOT registered. function _assertCycleDoesNotExist(bytes32 cycleId) private view { if (_exist(cycleId)) { revert CycleAlreadyRegistered(); } } // Ensure that cycle hasn't been executed before. function _assertCycleIsNotExecuted(bytes32 cycleId) private view { if (_cycles[cycleId].executed) { revert CycleAlreadyExecuted(); } } // Validate Instruction function _assertValidInstruction(Instruction memory instruction) private view { // Ensure that instruction doesn't exist by checking its amount. if (_instructions[instruction.id].amount > 0) { revert InstructionExists(instruction.id); } _assertValidInstructionData(instruction); } // Check that cycleId is registered by looking at instructions length, this function may change its logic later function _exist(bytes32 cycleId) private view returns (bool) { return _cycles[cycleId].instructions.length > 0; } // Build Deposit item from instruction function _buildDepositItem(Instruction memory instruction) private pure returns (DepositItem memory) { return DepositItem({ depositType: instruction.asset == address(0) ? DepositType.NATIVE : DepositType.ERC20, token: instruction.asset, instructionId: instruction.id }); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControl.sol) pragma solidity ^0.8.0; import "./IAccessControl.sol"; import "../utils/Context.sol"; import "../utils/Strings.sol"; import "../utils/introspection/ERC165.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role, _msgSender()); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(uint160(account), 20), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @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) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @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) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @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 revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } }
// SPDX-License-Identifier: Unlicense pragma solidity >=0.8.4; import "./SSCStructs.sol"; import "./Assertions.sol"; import "@rari-capital/solmate/src/utils/SafeTransferLib.sol"; import "@rari-capital/solmate/src/tokens/ERC20.sol"; /** * @title Vault * @notice Vault contains logic for making deposits and withdrawals of funds * to and from Settlements. */ contract SSCVault is Assertions { using SafeTransferLib for ERC20; // Events event Deposit(address indexed account, bytes32 instruction); event Withdraw(address indexed account, bytes32 instruction); // Track allocated funds to various instructions. mapping(bytes32 => uint256) internal _deposits; // Track sender of instruction mapping(bytes32 => address) internal _senderOf; /** * @notice Internal function to deposit and allocate funds to a instruction. * * @param item Contains data of the item to deposit. * @param instructionAmount Amount to deposit, if {item.depositType} is ETH, this * parameter MUST be {msg.value}. */ function _deposit(DepositItem memory item, uint256 instructionAmount) internal { _assertNonZeroAmount(instructionAmount, item.instructionId); _assertInstructionHasNoDeposits(item.instructionId); _deposits[item.instructionId] = instructionAmount; _senderOf[item.instructionId] = msg.sender; if (item.depositType == DepositType.ERC20) { ERC20(item.token).safeTransferFrom( msg.sender, address(this), instructionAmount ); } else { if (msg.value != instructionAmount) { revert InvalidSuppliedETHAmount(item.instructionId); } } emit Deposit(msg.sender, item.instructionId); } /** * @notice Internal function to withdraw funds from an instruction to {msg.sender}. * * @param item Contains data of the item to withdraw. */ function _withdraw(DepositItem memory item) internal { _assertAccountIsSender(msg.sender, item.instructionId); _withdrawTo(item, msg.sender); emit Withdraw(msg.sender, item.instructionId); } /** * @notice Internal to transfer allocated funds to a given account. * * @param item Contains data of the item to withdraw. * @param to Recipient of the withdrawal. */ function _withdrawTo(DepositItem memory item, address to) internal { uint256 amount = _deposits[item.instructionId]; _assertInstructionHasDeposits(item.instructionId); // empty deposited funds _deposits[item.instructionId] = 0; if (item.depositType == DepositType.ERC20) { ERC20(item.token).safeTransfer(to, amount); } else { SafeTransferLib.safeTransferETH(to, amount); } } // Ensure that an account is a sender of the instruction. function _assertAccountIsSender(address account, bytes32 instructionId) private view { // Revert if {account} is not sender. if (_senderOf[instructionId] != account) { revert NotASender(instructionId); } } // Ensure that required amount in a instruction is fullfiled. function _assertInstructionHasDeposits(bytes32 instructionId) private view { // Revert if the supplied amount is equal to zero. if (_deposits[instructionId] == 0) { revert NoDeposits(instructionId); } } // Ensure that required amount in a instruction is fullfiled. function _assertInstructionHasNoDeposits(bytes32 instructionId) private view { // Revert if the supplied amount is not equal to zero. if (_deposits[instructionId] != 0) { revert AlreadyDeposited(instructionId); } } }
// SPDX-License-Identifier: Unlicense pragma solidity >=0.8.4; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "../interfaces/MSSCErrors.sol"; import "./SSCStructs.sol"; /** * @title Assertions * @notice Assertions contains logic for making various assertions that do not * fit neatly within a dedicated semantic scope. */ contract Assertions is MSSCErrors { /** * @dev Internal view function to ensure that a given instruction tuple has valid data. * * @param instruction The instruction tuple to check. */ function _assertValidInstructionData(Instruction memory instruction) internal view { _assertNonZeroAmount(instruction.amount, instruction.id); _assertReceiverIsNotZeroAddress(instruction); _assertValidAsset(instruction); } /** * @dev Internal pure function to ensure that a given item amount is not * zero. * * @param amount The amount to check. */ function _assertNonZeroAmount(uint256 amount, bytes32 instructionId) internal pure { // Revert if the supplied amount is equal to zero. if (amount == 0) { revert ZeroAmount(instructionId); } } /** * @dev Internal view function to ensure that {sender} and {recipient} in a given * instruction are non-zero addresses. * * @param instruction The instruction tuple to check. */ function _assertReceiverIsNotZeroAddress(Instruction memory instruction) private pure { if (instruction.receiver == address(0)) { revert ReceiverIsZeroAddress(instruction.id); } } /** * @dev Internal view function to ensure that {asset} is a valid contract or null address * for ETH transfers. * * @param instruction The instruction tuple to check. */ function _assertValidAsset(Instruction memory instruction) private view { if ( instruction.asset.code.length <= 0 && instruction.asset != address(0) ) { revert InvalidAsset(instruction.id); } } }
// 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 IAccessControl { /** * @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/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @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] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// 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 IERC165 { /** * @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); }
// SPDX-License-Identifier: Unlicense pragma solidity >=0.8.4; import "./SSCEnums.sol"; struct Instruction { bytes32 id; address receiver; address asset; uint256 amount; } struct SettlementCycle { bytes32[] instructions; bool executed; } struct DepositItem { DepositType depositType; bytes32 instructionId; address token; } struct TransferDepositedItem { DepositItem depositItem; address to; uint256 amount; }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; import {ERC20} from "../tokens/ERC20.sol"; /// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SafeTransferLib.sol) /// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer. /// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller. library SafeTransferLib { /*////////////////////////////////////////////////////////////// ETH OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferETH(address to, uint256 amount) internal { bool success; assembly { // Transfer the ETH and store if it succeeded or not. success := call(gas(), to, amount, 0, 0, 0, 0) } require(success, "ETH_TRANSFER_FAILED"); } /*////////////////////////////////////////////////////////////// ERC20 OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferFrom( ERC20 token, address from, address to, uint256 amount ) internal { bool success; assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), from) // Append the "from" argument. mstore(add(freeMemoryPointer, 36), to) // Append the "to" argument. mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 100, 0, 32) ) } require(success, "TRANSFER_FROM_FAILED"); } function safeTransfer( ERC20 token, address to, uint256 amount ) internal { bool success; assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 68, 0, 32) ) } require(success, "TRANSFER_FAILED"); } function safeApprove( ERC20 token, address to, uint256 amount ) internal { bool success; assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 68, 0, 32) ) } require(success, "APPROVE_FAILED"); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Modern and gas efficient ERC20 + EIP-2612 implementation. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol) /// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol) /// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it. abstract contract ERC20 { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Transfer(address indexed from, address indexed to, uint256 amount); event Approval(address indexed owner, address indexed spender, uint256 amount); /*////////////////////////////////////////////////////////////// METADATA STORAGE //////////////////////////////////////////////////////////////*/ string public name; string public symbol; uint8 public immutable decimals; /*////////////////////////////////////////////////////////////// ERC20 STORAGE //////////////////////////////////////////////////////////////*/ uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; /*////////////////////////////////////////////////////////////// EIP-2612 STORAGE //////////////////////////////////////////////////////////////*/ uint256 internal immutable INITIAL_CHAIN_ID; bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR; mapping(address => uint256) public nonces; /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor( string memory _name, string memory _symbol, uint8 _decimals ) { name = _name; symbol = _symbol; decimals = _decimals; INITIAL_CHAIN_ID = block.chainid; INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator(); } /*////////////////////////////////////////////////////////////// ERC20 LOGIC //////////////////////////////////////////////////////////////*/ function approve(address spender, uint256 amount) public virtual returns (bool) { allowance[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } function transfer(address to, uint256 amount) public virtual returns (bool) { balanceOf[msg.sender] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(msg.sender, to, amount); return true; } function transferFrom( address from, address to, uint256 amount ) public virtual returns (bool) { uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; balanceOf[from] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(from, to, amount); return true; } /*////////////////////////////////////////////////////////////// EIP-2612 LOGIC //////////////////////////////////////////////////////////////*/ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual { require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED"); // Unchecked because the only math done is incrementing // the owner's nonce which cannot realistically overflow. unchecked { address recoveredAddress = ecrecover( keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR(), keccak256( abi.encode( keccak256( "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)" ), owner, spender, value, nonces[owner]++, deadline ) ) ) ), v, r, s ); require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER"); allowance[recoveredAddress][spender] = value; } emit Approval(owner, spender, value); } function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator(); } function computeDomainSeparator() internal view virtual returns (bytes32) { return keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256("1"), block.chainid, address(this) ) ); } /*////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint(address to, uint256 amount) internal virtual { totalSupply += amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(address(0), to, amount); } function _burn(address from, uint256 amount) internal virtual { balanceOf[from] -= amount; // Cannot underflow because a user's balance // will never be larger than the total supply. unchecked { totalSupply -= amount; } emit Transfer(from, address(0), amount); } }
// SPDX-License-Identifier: Unlicense pragma solidity >=0.8.4; enum DepositType { NATIVE, ERC20 }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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); /** * @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); }
// SPDX-License-Identifier: Unlicense pragma solidity >=0.8.4; /** * @title MSSCErrors */ interface MSSCErrors { /** * @dev Revert with an error when trying to register an existent Settlement Cycle. */ error CycleAlreadyRegistered(); /** * @dev Revert with an error when executing a previously executed Settlement Cycle. */ error CycleAlreadyExecuted(); /** * @dev Revert with an error when attempting to interact with a cycle that * does not yet exist. */ error NoCycle(); /** * @dev Revert with an error when attempting to register a cycle without a * single instruction. */ error CycleHasNoInstruction(); /** * @dev Revert with an error when trying to register an existent instruction. * * @param instruction The instruction that already exists. * */ error InstructionExists(bytes32 instruction); /** * @dev Revert with an error when attempting to interact with an instruction that * does not yet exist. * * @param instruction The instruction that doesn't exist. */ error NoInstruction(bytes32 instruction); /** * @dev Revert with an error when an asset of a instruction is invalid. * * @param instruction The instruction that contain the invalid asset. */ error InvalidAsset(bytes32 instruction); /** * @dev Revert with an error when attempting to register a receiver account * and supplying the null address. * * @param instruction The instruction that contain the zero address. */ error ReceiverIsZeroAddress(bytes32 instruction); /** * @dev Revert with an error when invalid ether is deposited for an instruction. * * @param instruction The instruction identifier of the attempted operation. */ error InvalidSuppliedETHAmount(bytes32 instruction); /** * @dev Revert with an error when an account is not a sender the instruction. * * @param instruction The instruction identifier of the attempted operation. */ error NotASender(bytes32 instruction); /** * @dev Revert with an error when attempting to register a Settlement with no amount. * * @param instruction The instruction identifier of the attempted operation. */ error ZeroAmount(bytes32 instruction); /** * @dev Revert with an error when a instruction has no deposits. * * @param instruction The instruction identifier of the attempted operation. */ error NoDeposits(bytes32 instruction); /** * @dev Revert with an error when a instruction has deposits. * * @param instruction The instruction identifier of the attempted operation. */ error AlreadyDeposited(bytes32 instruction); }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"payable","type":"constructor"},{"inputs":[{"internalType":"bytes32","name":"instruction","type":"bytes32"}],"name":"AlreadyDeposited","type":"error"},{"inputs":[],"name":"CycleAlreadyExecuted","type":"error"},{"inputs":[],"name":"CycleAlreadyRegistered","type":"error"},{"inputs":[],"name":"CycleHasNoInstruction","type":"error"},{"inputs":[{"internalType":"bytes32","name":"instruction","type":"bytes32"}],"name":"InstructionExists","type":"error"},{"inputs":[{"internalType":"bytes32","name":"instruction","type":"bytes32"}],"name":"InvalidAsset","type":"error"},{"inputs":[{"internalType":"bytes32","name":"instruction","type":"bytes32"}],"name":"InvalidSuppliedETHAmount","type":"error"},{"inputs":[],"name":"NoCycle","type":"error"},{"inputs":[{"internalType":"bytes32","name":"instruction","type":"bytes32"}],"name":"NoDeposits","type":"error"},{"inputs":[{"internalType":"bytes32","name":"instruction","type":"bytes32"}],"name":"NoInstruction","type":"error"},{"inputs":[{"internalType":"bytes32","name":"instruction","type":"bytes32"}],"name":"NotASender","type":"error"},{"inputs":[{"internalType":"bytes32","name":"instruction","type":"bytes32"}],"name":"ReceiverIsZeroAddress","type":"error"},{"inputs":[{"internalType":"bytes32","name":"instruction","type":"bytes32"}],"name":"ZeroAmount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bytes32","name":"instruction","type":"bytes32"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"cycleId","type":"bytes32"},{"indexed":false,"internalType":"bytes32[]","name":"instructions","type":"bytes32[]"}],"name":"ExecuteCycle","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"cycleId","type":"bytes32"},{"components":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"indexed":false,"internalType":"struct Instruction[]","name":"instructions","type":"tuple[]"}],"name":"RegisterCycle","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bytes32","name":"instruction","type":"bytes32"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MEMBRANE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"instructionId","type":"bytes32"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"instructionId","type":"bytes32"}],"name":"deposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"cycleId","type":"bytes32"}],"name":"executeInstructions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"cycleId","type":"bytes32"}],"name":"executed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"cycleId","type":"bytes32"}],"name":"getSettlementInstructions","outputs":[{"internalType":"bytes32[]","name":"","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"cycleId","type":"bytes32"},{"components":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Instruction[]","name":"instructions","type":"tuple[]"}],"name":"registerSettlementCycle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"cycleId","type":"bytes32"}],"name":"registered","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"instructionId","type":"bytes32"}],"name":"senderOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"instructionId","type":"bytes32"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6080604052620000286000801b6200001c6200006f60201b60201c565b6200007760201b60201c565b620000697f9b7ca6760b46d141ef3e8cd6c52392cbdb36330c2dddca48ff8b5c7cc6fe91776200005d6200006f60201b60201c565b6200007760201b60201c565b620001d4565b600033905090565b6200008982826200016960201b60201c565b620001655760016002600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506200010a6200006f60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b60006002600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b612a6680620001e46000396000f3fe6080604052600436106100fe5760003560e01c80638e19899e11610095578063afba522e11610064578063afba522e1461037d578063b214faa5146103a8578063d547741f146103c4578063d95d9e10146103ed578063dcdc845214610416576100fe565b80638e19899e146102af57806391d14854146102d8578063a217fddf14610315578063a9fcfb3314610340576100fe565b806336568abe116100d157806336568abe146101e35780633d4dff7b1461020c57806351faf10a146102495780635524d54814610272576100fe565b806301ffc9a7146101035780631d8490ff14610140578063248a9ca31461017d5780632f2ff15d146101ba575b600080fd5b34801561010f57600080fd5b5061012a6004803603810190610125919061203f565b610453565b6040516101379190612454565b60405180910390f35b34801561014c57600080fd5b5061016760048036038101906101629190611f82565b6104cd565b60405161017491906123f3565b60405180910390f35b34801561018957600080fd5b506101a4600480360381019061019f9190611f82565b61050a565b6040516101b1919061246f565b60405180910390f35b3480156101c657600080fd5b506101e160048036038101906101dc9190611fab565b61052a565b005b3480156101ef57600080fd5b5061020a60048036038101906102059190611fab565b610553565b005b34801561021857600080fd5b50610233600480360381019061022e9190611f82565b6105d6565b604051610240919061254c565b60405180910390f35b34801561025557600080fd5b50610270600480360381019061026b9190611fe7565b6105f2565b005b34801561027e57600080fd5b5061029960048036038101906102949190611f82565b61082b565b6040516102a69190612454565b60405180910390f35b3480156102bb57600080fd5b506102d660048036038101906102d19190611f82565b61083d565b005b3480156102e457600080fd5b506102ff60048036038101906102fa9190611fab565b610934565b60405161030c9190612454565b60405180910390f35b34801561032157600080fd5b5061032a61099f565b604051610337919061246f565b60405180910390f35b34801561034c57600080fd5b5061036760048036038101906103629190611f82565b6109a6565b6040516103749190612454565b60405180910390f35b34801561038957600080fd5b506103926109dc565b60405161039f919061246f565b60405180910390f35b6103c260048036038101906103bd9190611f82565b610a00565b005b3480156103d057600080fd5b506103eb60048036038101906103e69190611fab565b610b4e565b005b3480156103f957600080fd5b50610414600480360381019061040f9190611f82565b610b77565b005b34801561042257600080fd5b5061043d60048036038101906104389190611f82565b610dba565b60405161044a919061240e565b60405180910390f35b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806104c657506104c582610e31565b5b9050919050565b60006001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600060026000838152602001908152602001600020600101549050919050565b6105338261050a565b6105448161053f610e9b565b610ea3565b61054e8383610f40565b505050565b61055b610e9b565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146105c8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105bf9061252c565b60405180910390fd5b6105d28282611021565b5050565b6000806000838152602001908152602001600020549050919050565b7f9b7ca6760b46d141ef3e8cd6c52392cbdb36330c2dddca48ff8b5c7cc6fe91776106248161061f610e9b565b610ea3565b61062d84611103565b60008383905090506000811415610670576040517fd0a3ad0400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060036000878152602001908152602001600020600001905060005b828110156107e85760008686838181106106d0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050608002018036038101906106e69190612068565b90506000816000015190506106fa82611146565b8381908060018154018082558091505060019003906000526020600020016000909190919091505581600460008381526020019081526020016000206000820151816000015560208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160030155905050826001019250505061068d565b50857fe814268b0134f15e824b849b4d0c59ad03d90e5eb2fb99625ee9855d5af994f3868660405161081b929190612430565b60405180910390a2505050505050565b6000610836826111b6565b9050919050565b600061092560046000848152602001908152602001600020604051806080016040529081600082015481526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016003820154815250506111db565b90506109308161129c565b5050565b60006002600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000801b81565b60006109b182611309565b6003600083815260200190815260200160002060010160009054906101000a900460ff169050919050565b7f9b7ca6760b46d141ef3e8cd6c52392cbdb36330c2dddca48ff8b5c7cc6fe917781565b600060046000838152602001908152602001600020604051806080016040529081600082015481526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160038201548152505090506000816060015190506000811415610b3157826040517f88e1e465000000000000000000000000000000000000000000000000000000008152600401610b28919061246f565b60405180910390fd5b6000610b3c836111db565b9050610b48818361134b565b50505050565b610b578261050a565b610b6881610b63610e9b565b610ea3565b610b728383611021565b505050565b610b8081611309565b610b8981611528565b60016003600083815260200190815260200160002060010160006101000a81548160ff021916908315150217905550600060036000838152602001908152602001600020600001805480602002602001604051908101604052809291908181526020018280548015610c1a57602002820191906000526020600020905b815481526020019060010190808311610c06575b5050505050905060008151905060005b81811015610d7c57600060046000858481518110610c71577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101518152602001908152602001600020604051806080016040529081600082015481526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160038201548152505090506000610d5f826111db565b9050610d6f818360200151611586565b8260010192505050610c2a565b50827fe1716c4390699a47ebe002ec1f1cb122604a88a8ebbc9ee984df53823c9be53c83604051610dad919061240e565b60405180910390a2505050565b6060610dc582611309565b60036000838152602001908152602001600020600001805480602002602001604051908101604052809291908181526020018280548015610e2557602002820191906000526020600020905b815481526020019060010190808311610e11575b50505050509050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b610ead8282610934565b610f3c57610ed28173ffffffffffffffffffffffffffffffffffffffff16601461168a565b610ee08360001c602061168a565b604051602001610ef19291906123b9565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f33919061248a565b60405180910390fd5b5050565b610f4a8282610934565b61101d5760016002600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550610fc2610e9b565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b61102b8282610934565b156110ff5760006002600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506110a4610e9b565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b61110c816111b6565b15611143576040517f4339c2c100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b600060046000836000015181526020019081526020016000206003015411156111aa5780600001516040517f3f5aa1500000000000000000000000000000000000000000000000000000000081526004016111a1919061246f565b60405180910390fd5b6111b381611984565b50565b6000806003600084815260200190815260200160002060000180549050119050919050565b6111e3611dfe565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff16846040015173ffffffffffffffffffffffffffffffffffffffff161461122d576001611230565b60005b6001811115611268577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b815260200183600001518152602001836040015173ffffffffffffffffffffffffffffffffffffffff168152509050919050565b6112aa3382602001516119ab565b6112b48133611586565b3373ffffffffffffffffffffffffffffffffffffffff167fb18c630f7b4f080f2ce1a87d68860e67aef56b0978e448ed92312da4eebeb16082602001516040516112fe919061246f565b60405180910390a250565b611312816111b6565b611348576040517fe6831b5a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b611359818360200151611a52565b6113668260200151611a9c565b80600080846020015181526020019081526020016000208190555033600160008460200151815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600180811115611410577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8260000151600181111561144d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b141561148957611484333083856040015173ffffffffffffffffffffffffffffffffffffffff16611af6909392919063ffffffff16565b6114d2565b8034146114d15781602001516040517f424c634c0000000000000000000000000000000000000000000000000000000081526004016114c8919061246f565b60405180910390fd5b5b3373ffffffffffffffffffffffffffffffffffffffff167f678afb2e81183654e6389bac063af1933c7935f97aceeae5aaa51bc54662cf88836020015160405161151c919061246f565b60405180910390a25050565b6003600082815260200190815260200160002060010160009054906101000a900460ff1615611583576040517ff8d3a35500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b6000806000846020015181526020019081526020016000205490506115ae8360200151611b95565b60008060008560200151815260200190815260200160002081905550600180811115611603577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b83600001516001811115611640577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b141561167a576116758282856040015173ffffffffffffffffffffffffffffffffffffffff16611bf09092919063ffffffff16565b611685565b6116848282611c88565b5b505050565b60606000600283600261169d91906126ba565b6116a79190612664565b67ffffffffffffffff8111156116e6577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156117185781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110611776577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611800577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000600184600261184091906126ba565b61184a9190612664565b90505b6001811115611936577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106118b2577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b1a60f81b8282815181106118ef577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c94508061192f906127c5565b905061184d565b506000841461197a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611971906124ac565b60405180910390fd5b8091505092915050565b61199681606001518260000151611a52565b61199f81611cdb565b6119a881611d58565b50565b8173ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611a4e57806040517ffd8dd8e4000000000000000000000000000000000000000000000000000000008152600401611a45919061246f565b60405180910390fd5b5050565b6000821415611a9857806040517f01802671000000000000000000000000000000000000000000000000000000008152600401611a8f919061246f565b60405180910390fd5b5050565b60008060008381526020019081526020016000205414611af357806040517faed8b686000000000000000000000000000000000000000000000000000000008152600401611aea919061246f565b60405180910390fd5b50565b60006040517f23b872dd0000000000000000000000000000000000000000000000000000000081528460048201528360248201528260448201526020600060648360008a5af13d15601f3d1160016000511416171691505080611b8e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b85906124cc565b60405180910390fd5b5050505050565b6000806000838152602001908152602001600020541415611bed57806040517f6fb4fb32000000000000000000000000000000000000000000000000000000008152600401611be4919061246f565b60405180910390fd5b50565b60006040517fa9059cbb000000000000000000000000000000000000000000000000000000008152836004820152826024820152602060006044836000895af13d15601f3d1160016000511416171691505080611c82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c79906124ec565b60405180910390fd5b50505050565b600080600080600085875af1905080611cd6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ccd9061250c565b60405180910390fd5b505050565b600073ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff161415611d555780600001516040517fa8bff4b3000000000000000000000000000000000000000000000000000000008152600401611d4c919061246f565b60405180910390fd5b50565b6000816040015173ffffffffffffffffffffffffffffffffffffffff163b11158015611db55750600073ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1614155b15611dfb5780600001516040517f8196d462000000000000000000000000000000000000000000000000000000008152600401611df2919061246f565b60405180910390fd5b50565b604051806060016040528060006001811115611e43577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b815260200160008019168152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b600081359050611e7f816129d4565b92915050565b60008083601f840112611e9757600080fd5b8235905067ffffffffffffffff811115611eb057600080fd5b602083019150836080820283011115611ec857600080fd5b9250929050565b600081359050611ede816129eb565b92915050565b600081359050611ef381612a02565b92915050565b600060808284031215611f0b57600080fd5b611f156080612567565b90506000611f2584828501611ecf565b6000830152506020611f3984828501611e70565b6020830152506040611f4d84828501611e70565b6040830152506060611f6184828501611f6d565b60608301525092915050565b600081359050611f7c81612a19565b92915050565b600060208284031215611f9457600080fd5b6000611fa284828501611ecf565b91505092915050565b60008060408385031215611fbe57600080fd5b6000611fcc85828601611ecf565b9250506020611fdd85828601611e70565b9150509250929050565b600080600060408486031215611ffc57600080fd5b600061200a86828701611ecf565b935050602084013567ffffffffffffffff81111561202757600080fd5b61203386828701611e85565b92509250509250925092565b60006020828403121561205157600080fd5b600061205f84828501611ee4565b91505092915050565b60006080828403121561207a57600080fd5b600061208884828501611ef9565b91505092915050565b600061209d83836121a9565b60208301905092915050565b60006120b58383612326565b60808301905092915050565b6120ca81612714565b82525050565b6120d981612714565b82525050565b60006120ea826125a6565b6120f481856125d6565b93506120ff8361258c565b8060005b838110156121305781516121178882612091565b9750612122836125bc565b925050600181019050612103565b5085935050505092915050565b600061214983856125e7565b93506121548261259c565b8060005b8581101561218d5761216a8284612642565b61217488826120a9565b975061217f836125c9565b925050600181019050612158565b5085925050509392505050565b6121a381612726565b82525050565b6121b281612732565b82525050565b6121c181612732565b82525050565b60006121d2826125b1565b6121dc81856125f8565b93506121ec818560208601612792565b6121f58161287e565b840191505092915050565b600061220b826125b1565b6122158185612609565b9350612225818560208601612792565b80840191505092915050565b600061223e6020836125f8565b91506122498261288f565b602082019050919050565b60006122616014836125f8565b915061226c826128b8565b602082019050919050565b6000612284600f836125f8565b915061228f826128e1565b602082019050919050565b60006122a76013836125f8565b91506122b28261290a565b602082019050919050565b60006122ca601783612609565b91506122d582612933565b601782019050919050565b60006122ed601183612609565b91506122f88261295c565b601182019050919050565b6000612310602f836125f8565b915061231b82612985565b604082019050919050565b60808201612337600083018361262b565b61234460008501826121a9565b506123526020830183612614565b61235f60208501826120c1565b5061236d6040830183612614565b61237a60408501826120c1565b50612388606083018361264d565b612395606085018261239b565b50505050565b6123a481612788565b82525050565b6123b381612788565b82525050565b60006123c4826122bd565b91506123d08285612200565b91506123db826122e0565b91506123e78284612200565b91508190509392505050565b600060208201905061240860008301846120d0565b92915050565b6000602082019050818103600083015261242881846120df565b905092915050565b6000602082019050818103600083015261244b81848661213d565b90509392505050565b6000602082019050612469600083018461219a565b92915050565b600060208201905061248460008301846121b8565b92915050565b600060208201905081810360008301526124a481846121c7565b905092915050565b600060208201905081810360008301526124c581612231565b9050919050565b600060208201905081810360008301526124e581612254565b9050919050565b6000602082019050818103600083015261250581612277565b9050919050565b600060208201905081810360008301526125258161229a565b9050919050565b6000602082019050818103600083015261254581612303565b9050919050565b600060208201905061256160008301846123aa565b92915050565b6000612571612582565b905061257d82826127ef565b919050565b6000604051905090565b6000819050602082019050919050565b6000819050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000608082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b60006126236020840184611e70565b905092915050565b600061263a6020840184611ecf565b905092915050565b600082905092915050565b600061265c6020840184611f6d565b905092915050565b600061266f82612788565b915061267a83612788565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156126af576126ae612820565b5b828201905092915050565b60006126c582612788565b91506126d083612788565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561270957612708612820565b5b828202905092915050565b600061271f82612768565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60005b838110156127b0578082015181840152602081019050612795565b838111156127bf576000848401525b50505050565b60006127d082612788565b915060008214156127e4576127e3612820565b5b600182039050919050565b6127f88261287e565b810181811067ffffffffffffffff821117156128175761281661284f565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b7f5452414e534645525f46524f4d5f4641494c4544000000000000000000000000600082015250565b7f5452414e534645525f4641494c45440000000000000000000000000000000000600082015250565b7f4554485f5452414e534645525f4641494c454400000000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b6129dd81612714565b81146129e857600080fd5b50565b6129f481612732565b81146129ff57600080fd5b50565b612a0b8161273c565b8114612a1657600080fd5b50565b612a2281612788565b8114612a2d57600080fd5b5056fea264697066735822122095be7bd6d87af045c83d18c4bcb81f29c9dc5065b4e57715075af012ffad2b6a64736f6c63430008040033
Deployed Bytecode
0x6080604052600436106100fe5760003560e01c80638e19899e11610095578063afba522e11610064578063afba522e1461037d578063b214faa5146103a8578063d547741f146103c4578063d95d9e10146103ed578063dcdc845214610416576100fe565b80638e19899e146102af57806391d14854146102d8578063a217fddf14610315578063a9fcfb3314610340576100fe565b806336568abe116100d157806336568abe146101e35780633d4dff7b1461020c57806351faf10a146102495780635524d54814610272576100fe565b806301ffc9a7146101035780631d8490ff14610140578063248a9ca31461017d5780632f2ff15d146101ba575b600080fd5b34801561010f57600080fd5b5061012a6004803603810190610125919061203f565b610453565b6040516101379190612454565b60405180910390f35b34801561014c57600080fd5b5061016760048036038101906101629190611f82565b6104cd565b60405161017491906123f3565b60405180910390f35b34801561018957600080fd5b506101a4600480360381019061019f9190611f82565b61050a565b6040516101b1919061246f565b60405180910390f35b3480156101c657600080fd5b506101e160048036038101906101dc9190611fab565b61052a565b005b3480156101ef57600080fd5b5061020a60048036038101906102059190611fab565b610553565b005b34801561021857600080fd5b50610233600480360381019061022e9190611f82565b6105d6565b604051610240919061254c565b60405180910390f35b34801561025557600080fd5b50610270600480360381019061026b9190611fe7565b6105f2565b005b34801561027e57600080fd5b5061029960048036038101906102949190611f82565b61082b565b6040516102a69190612454565b60405180910390f35b3480156102bb57600080fd5b506102d660048036038101906102d19190611f82565b61083d565b005b3480156102e457600080fd5b506102ff60048036038101906102fa9190611fab565b610934565b60405161030c9190612454565b60405180910390f35b34801561032157600080fd5b5061032a61099f565b604051610337919061246f565b60405180910390f35b34801561034c57600080fd5b5061036760048036038101906103629190611f82565b6109a6565b6040516103749190612454565b60405180910390f35b34801561038957600080fd5b506103926109dc565b60405161039f919061246f565b60405180910390f35b6103c260048036038101906103bd9190611f82565b610a00565b005b3480156103d057600080fd5b506103eb60048036038101906103e69190611fab565b610b4e565b005b3480156103f957600080fd5b50610414600480360381019061040f9190611f82565b610b77565b005b34801561042257600080fd5b5061043d60048036038101906104389190611f82565b610dba565b60405161044a919061240e565b60405180910390f35b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806104c657506104c582610e31565b5b9050919050565b60006001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600060026000838152602001908152602001600020600101549050919050565b6105338261050a565b6105448161053f610e9b565b610ea3565b61054e8383610f40565b505050565b61055b610e9b565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146105c8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105bf9061252c565b60405180910390fd5b6105d28282611021565b5050565b6000806000838152602001908152602001600020549050919050565b7f9b7ca6760b46d141ef3e8cd6c52392cbdb36330c2dddca48ff8b5c7cc6fe91776106248161061f610e9b565b610ea3565b61062d84611103565b60008383905090506000811415610670576040517fd0a3ad0400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060036000878152602001908152602001600020600001905060005b828110156107e85760008686838181106106d0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050608002018036038101906106e69190612068565b90506000816000015190506106fa82611146565b8381908060018154018082558091505060019003906000526020600020016000909190919091505581600460008381526020019081526020016000206000820151816000015560208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160030155905050826001019250505061068d565b50857fe814268b0134f15e824b849b4d0c59ad03d90e5eb2fb99625ee9855d5af994f3868660405161081b929190612430565b60405180910390a2505050505050565b6000610836826111b6565b9050919050565b600061092560046000848152602001908152602001600020604051806080016040529081600082015481526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016003820154815250506111db565b90506109308161129c565b5050565b60006002600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000801b81565b60006109b182611309565b6003600083815260200190815260200160002060010160009054906101000a900460ff169050919050565b7f9b7ca6760b46d141ef3e8cd6c52392cbdb36330c2dddca48ff8b5c7cc6fe917781565b600060046000838152602001908152602001600020604051806080016040529081600082015481526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160038201548152505090506000816060015190506000811415610b3157826040517f88e1e465000000000000000000000000000000000000000000000000000000008152600401610b28919061246f565b60405180910390fd5b6000610b3c836111db565b9050610b48818361134b565b50505050565b610b578261050a565b610b6881610b63610e9b565b610ea3565b610b728383611021565b505050565b610b8081611309565b610b8981611528565b60016003600083815260200190815260200160002060010160006101000a81548160ff021916908315150217905550600060036000838152602001908152602001600020600001805480602002602001604051908101604052809291908181526020018280548015610c1a57602002820191906000526020600020905b815481526020019060010190808311610c06575b5050505050905060008151905060005b81811015610d7c57600060046000858481518110610c71577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101518152602001908152602001600020604051806080016040529081600082015481526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160038201548152505090506000610d5f826111db565b9050610d6f818360200151611586565b8260010192505050610c2a565b50827fe1716c4390699a47ebe002ec1f1cb122604a88a8ebbc9ee984df53823c9be53c83604051610dad919061240e565b60405180910390a2505050565b6060610dc582611309565b60036000838152602001908152602001600020600001805480602002602001604051908101604052809291908181526020018280548015610e2557602002820191906000526020600020905b815481526020019060010190808311610e11575b50505050509050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b610ead8282610934565b610f3c57610ed28173ffffffffffffffffffffffffffffffffffffffff16601461168a565b610ee08360001c602061168a565b604051602001610ef19291906123b9565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f33919061248a565b60405180910390fd5b5050565b610f4a8282610934565b61101d5760016002600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550610fc2610e9b565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b61102b8282610934565b156110ff5760006002600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506110a4610e9b565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b61110c816111b6565b15611143576040517f4339c2c100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b600060046000836000015181526020019081526020016000206003015411156111aa5780600001516040517f3f5aa1500000000000000000000000000000000000000000000000000000000081526004016111a1919061246f565b60405180910390fd5b6111b381611984565b50565b6000806003600084815260200190815260200160002060000180549050119050919050565b6111e3611dfe565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff16846040015173ffffffffffffffffffffffffffffffffffffffff161461122d576001611230565b60005b6001811115611268577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b815260200183600001518152602001836040015173ffffffffffffffffffffffffffffffffffffffff168152509050919050565b6112aa3382602001516119ab565b6112b48133611586565b3373ffffffffffffffffffffffffffffffffffffffff167fb18c630f7b4f080f2ce1a87d68860e67aef56b0978e448ed92312da4eebeb16082602001516040516112fe919061246f565b60405180910390a250565b611312816111b6565b611348576040517fe6831b5a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b611359818360200151611a52565b6113668260200151611a9c565b80600080846020015181526020019081526020016000208190555033600160008460200151815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600180811115611410577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8260000151600181111561144d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b141561148957611484333083856040015173ffffffffffffffffffffffffffffffffffffffff16611af6909392919063ffffffff16565b6114d2565b8034146114d15781602001516040517f424c634c0000000000000000000000000000000000000000000000000000000081526004016114c8919061246f565b60405180910390fd5b5b3373ffffffffffffffffffffffffffffffffffffffff167f678afb2e81183654e6389bac063af1933c7935f97aceeae5aaa51bc54662cf88836020015160405161151c919061246f565b60405180910390a25050565b6003600082815260200190815260200160002060010160009054906101000a900460ff1615611583576040517ff8d3a35500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b6000806000846020015181526020019081526020016000205490506115ae8360200151611b95565b60008060008560200151815260200190815260200160002081905550600180811115611603577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b83600001516001811115611640577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b141561167a576116758282856040015173ffffffffffffffffffffffffffffffffffffffff16611bf09092919063ffffffff16565b611685565b6116848282611c88565b5b505050565b60606000600283600261169d91906126ba565b6116a79190612664565b67ffffffffffffffff8111156116e6577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156117185781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110611776577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611800577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000600184600261184091906126ba565b61184a9190612664565b90505b6001811115611936577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106118b2577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b1a60f81b8282815181106118ef577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c94508061192f906127c5565b905061184d565b506000841461197a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611971906124ac565b60405180910390fd5b8091505092915050565b61199681606001518260000151611a52565b61199f81611cdb565b6119a881611d58565b50565b8173ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611a4e57806040517ffd8dd8e4000000000000000000000000000000000000000000000000000000008152600401611a45919061246f565b60405180910390fd5b5050565b6000821415611a9857806040517f01802671000000000000000000000000000000000000000000000000000000008152600401611a8f919061246f565b60405180910390fd5b5050565b60008060008381526020019081526020016000205414611af357806040517faed8b686000000000000000000000000000000000000000000000000000000008152600401611aea919061246f565b60405180910390fd5b50565b60006040517f23b872dd0000000000000000000000000000000000000000000000000000000081528460048201528360248201528260448201526020600060648360008a5af13d15601f3d1160016000511416171691505080611b8e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b85906124cc565b60405180910390fd5b5050505050565b6000806000838152602001908152602001600020541415611bed57806040517f6fb4fb32000000000000000000000000000000000000000000000000000000008152600401611be4919061246f565b60405180910390fd5b50565b60006040517fa9059cbb000000000000000000000000000000000000000000000000000000008152836004820152826024820152602060006044836000895af13d15601f3d1160016000511416171691505080611c82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c79906124ec565b60405180910390fd5b50505050565b600080600080600085875af1905080611cd6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ccd9061250c565b60405180910390fd5b505050565b600073ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff161415611d555780600001516040517fa8bff4b3000000000000000000000000000000000000000000000000000000008152600401611d4c919061246f565b60405180910390fd5b50565b6000816040015173ffffffffffffffffffffffffffffffffffffffff163b11158015611db55750600073ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff1614155b15611dfb5780600001516040517f8196d462000000000000000000000000000000000000000000000000000000008152600401611df2919061246f565b60405180910390fd5b50565b604051806060016040528060006001811115611e43577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b815260200160008019168152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b600081359050611e7f816129d4565b92915050565b60008083601f840112611e9757600080fd5b8235905067ffffffffffffffff811115611eb057600080fd5b602083019150836080820283011115611ec857600080fd5b9250929050565b600081359050611ede816129eb565b92915050565b600081359050611ef381612a02565b92915050565b600060808284031215611f0b57600080fd5b611f156080612567565b90506000611f2584828501611ecf565b6000830152506020611f3984828501611e70565b6020830152506040611f4d84828501611e70565b6040830152506060611f6184828501611f6d565b60608301525092915050565b600081359050611f7c81612a19565b92915050565b600060208284031215611f9457600080fd5b6000611fa284828501611ecf565b91505092915050565b60008060408385031215611fbe57600080fd5b6000611fcc85828601611ecf565b9250506020611fdd85828601611e70565b9150509250929050565b600080600060408486031215611ffc57600080fd5b600061200a86828701611ecf565b935050602084013567ffffffffffffffff81111561202757600080fd5b61203386828701611e85565b92509250509250925092565b60006020828403121561205157600080fd5b600061205f84828501611ee4565b91505092915050565b60006080828403121561207a57600080fd5b600061208884828501611ef9565b91505092915050565b600061209d83836121a9565b60208301905092915050565b60006120b58383612326565b60808301905092915050565b6120ca81612714565b82525050565b6120d981612714565b82525050565b60006120ea826125a6565b6120f481856125d6565b93506120ff8361258c565b8060005b838110156121305781516121178882612091565b9750612122836125bc565b925050600181019050612103565b5085935050505092915050565b600061214983856125e7565b93506121548261259c565b8060005b8581101561218d5761216a8284612642565b61217488826120a9565b975061217f836125c9565b925050600181019050612158565b5085925050509392505050565b6121a381612726565b82525050565b6121b281612732565b82525050565b6121c181612732565b82525050565b60006121d2826125b1565b6121dc81856125f8565b93506121ec818560208601612792565b6121f58161287e565b840191505092915050565b600061220b826125b1565b6122158185612609565b9350612225818560208601612792565b80840191505092915050565b600061223e6020836125f8565b91506122498261288f565b602082019050919050565b60006122616014836125f8565b915061226c826128b8565b602082019050919050565b6000612284600f836125f8565b915061228f826128e1565b602082019050919050565b60006122a76013836125f8565b91506122b28261290a565b602082019050919050565b60006122ca601783612609565b91506122d582612933565b601782019050919050565b60006122ed601183612609565b91506122f88261295c565b601182019050919050565b6000612310602f836125f8565b915061231b82612985565b604082019050919050565b60808201612337600083018361262b565b61234460008501826121a9565b506123526020830183612614565b61235f60208501826120c1565b5061236d6040830183612614565b61237a60408501826120c1565b50612388606083018361264d565b612395606085018261239b565b50505050565b6123a481612788565b82525050565b6123b381612788565b82525050565b60006123c4826122bd565b91506123d08285612200565b91506123db826122e0565b91506123e78284612200565b91508190509392505050565b600060208201905061240860008301846120d0565b92915050565b6000602082019050818103600083015261242881846120df565b905092915050565b6000602082019050818103600083015261244b81848661213d565b90509392505050565b6000602082019050612469600083018461219a565b92915050565b600060208201905061248460008301846121b8565b92915050565b600060208201905081810360008301526124a481846121c7565b905092915050565b600060208201905081810360008301526124c581612231565b9050919050565b600060208201905081810360008301526124e581612254565b9050919050565b6000602082019050818103600083015261250581612277565b9050919050565b600060208201905081810360008301526125258161229a565b9050919050565b6000602082019050818103600083015261254581612303565b9050919050565b600060208201905061256160008301846123aa565b92915050565b6000612571612582565b905061257d82826127ef565b919050565b6000604051905090565b6000819050602082019050919050565b6000819050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000608082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b60006126236020840184611e70565b905092915050565b600061263a6020840184611ecf565b905092915050565b600082905092915050565b600061265c6020840184611f6d565b905092915050565b600061266f82612788565b915061267a83612788565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156126af576126ae612820565b5b828201905092915050565b60006126c582612788565b91506126d083612788565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561270957612708612820565b5b828202905092915050565b600061271f82612768565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60005b838110156127b0578082015181840152602081019050612795565b838111156127bf576000848401525b50505050565b60006127d082612788565b915060008214156127e4576127e3612820565b5b600182039050919050565b6127f88261287e565b810181811067ffffffffffffffff821117156128175761281661284f565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b7f5452414e534645525f46524f4d5f4641494c4544000000000000000000000000600082015250565b7f5452414e534645525f4641494c45440000000000000000000000000000000000600082015250565b7f4554485f5452414e534645525f4641494c454400000000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b6129dd81612714565b81146129e857600080fd5b50565b6129f481612732565b81146129ff57600080fd5b50565b612a0b8161273c565b8114612a1657600080fd5b50565b612a2281612788565b8114612a2d57600080fd5b5056fea264697066735822122095be7bd6d87af045c83d18c4bcb81f29c9dc5065b4e57715075af012ffad2b6a64736f6c63430008040033
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ 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.