Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Multichain Info
No addresses found
Latest 19 from a total of 19 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Create | 21877626 | 36 days ago | IN | 0 ETH | 0.00094563 | ||||
Create | 21834935 | 42 days ago | IN | 0 ETH | 0.00127296 | ||||
Create | 21815257 | 45 days ago | IN | 0 ETH | 0.00075815 | ||||
Create | 21786715 | 49 days ago | IN | 0 ETH | 0.00113722 | ||||
Create | 20718615 | 198 days ago | IN | 0 ETH | 0.00120625 | ||||
Create | 20717761 | 198 days ago | IN | 0 ETH | 0.00078437 | ||||
Create | 20532790 | 224 days ago | IN | 0 ETH | 0.00078441 | ||||
Create | 19609554 | 353 days ago | IN | 0 ETH | 0.00531464 | ||||
Create | 18517120 | 506 days ago | IN | 0 ETH | 0.01229256 | ||||
Create | 18432903 | 518 days ago | IN | 0 ETH | 0.01922205 | ||||
Create | 18432330 | 518 days ago | IN | 0 ETH | 0.015217 | ||||
Create | 18428346 | 519 days ago | IN | 0 ETH | 0.01568963 | ||||
Create | 18419298 | 520 days ago | IN | 0 ETH | 0.02082358 | ||||
Transfer | 18419175 | 520 days ago | IN | 0 ETH | 0.00044247 | ||||
Create | 17669882 | 625 days ago | IN | 0 ETH | 0.01361541 | ||||
Create | 17669837 | 625 days ago | IN | 0 ETH | 0.01361521 | ||||
Create | 17650115 | 628 days ago | IN | 0 ETH | 0.04645191 | ||||
Create | 15449874 | 938 days ago | IN | 0 ETH | 0.01362854 | ||||
Create | 14965313 | 1016 days ago | IN | 0 ETH | 0.01212812 |
Latest 18 internal transactions
Advanced mode:
Parent Transaction Hash | Method | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|---|
0x60a06040 | 21877626 | 36 days ago | Contract Creation | 0 ETH | |||
0x60a06040 | 21834935 | 42 days ago | Contract Creation | 0 ETH | |||
0x60a06040 | 21815257 | 45 days ago | Contract Creation | 0 ETH | |||
0x60a06040 | 21786715 | 49 days ago | Contract Creation | 0 ETH | |||
0x60a06040 | 20718615 | 198 days ago | Contract Creation | 0 ETH | |||
0x60a06040 | 20717761 | 198 days ago | Contract Creation | 0 ETH | |||
0x60a06040 | 20532790 | 224 days ago | Contract Creation | 0 ETH | |||
0x60a06040 | 19609554 | 353 days ago | Contract Creation | 0 ETH | |||
0x60a06040 | 18517120 | 506 days ago | Contract Creation | 0 ETH | |||
0x60a06040 | 18432903 | 518 days ago | Contract Creation | 0 ETH | |||
0x60a06040 | 18432330 | 518 days ago | Contract Creation | 0 ETH | |||
0x60a06040 | 18428346 | 519 days ago | Contract Creation | 0 ETH | |||
0x60a06040 | 18419298 | 520 days ago | Contract Creation | 0 ETH | |||
0x60a06040 | 17669882 | 625 days ago | Contract Creation | 0 ETH | |||
0x60a06040 | 17669837 | 625 days ago | Contract Creation | 0 ETH | |||
0x60a06040 | 17650115 | 628 days ago | Contract Creation | 0 ETH | |||
0x60a06040 | 15449874 | 938 days ago | Contract Creation | 0 ETH | |||
- | 14965313 | 1016 days ago | Contract Creation | 0 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
MultiSignWalletFactory
Compiler Version
v0.8.0+commit.c7dfd78e
Contract Source Code (Solidity Multiple files format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.0; import "./MultiSignWalletProxy.sol"; import "./IMultiSignWalletFactory.sol"; contract MultiSignWalletFactory is IMultiSignWalletFactory { address payable immutable private walletImpl; event NewWallet(address indexed wallet); bytes4 internal constant _INITIALIZE = bytes4(keccak256(bytes("initialize(address[],uint256,bool,uint256,address[])"))); constructor(address payable _walletImpl) { walletImpl = _walletImpl; } function create(address[] calldata _owners, uint _required, bytes32 salt, bool _securitySwitch, uint _inactiveInterval, address[] calldata _execptionTokens) public returns (address) { MultiSignWalletProxy wallet = new MultiSignWalletProxy{salt: salt}(); (bool success, bytes memory data) = address(wallet).call(abi.encodeWithSelector(_INITIALIZE, _owners, _required, _securitySwitch, _inactiveInterval, _execptionTokens)); require(success && (data.length == 0 || abi.decode(data, (bool))), "create wallet failed"); emit NewWallet(address(wallet)); return address(wallet); } function getWalletImpl() external override view returns(address) { return walletImpl; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Address.sol) pragma solidity 0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (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 `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, 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 `sender` to `recipient` 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 sender, address recipient, 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: MIT pragma solidity 0.8.0; interface IMultiSignWalletFactory { function getWalletImpl() external view returns(address) ; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.0; import "./SafeMath256.sol"; import "./IERC20.sol"; import "./SafeERC20.sol"; import "./SignMessage.sol"; contract WalletOwner { uint16 constant MIN_REQUIRED = 1; uint256 required; mapping(address => uint256) activeOwners; address[] owners; mapping(address => uint256) exceptionTokens; event OwnerRemoval(address indexed owner); event OwnerAddition(address indexed owner); event SignRequirementChanged(uint256 required); function getOwners() public view returns (address[] memory) { return owners; } function getOwnerRequiredParam() public view returns (uint256) { return required; } function isOwner(address addr) public view returns (bool) { return activeOwners[addr] > 0; } } contract WalletSecurity { uint256 constant MIN_INACTIVE_INTERVAL = 3 days; // 3days; uint256 constant securityInterval = 3 days; bool initialized; bool securitySwitch = false; uint256 deactivatedInterval = 0; uint256 lastActivatedTime = 0; mapping(bytes32 => uint256) transactions; event SecuritySwitchChange(bool swithOn, uint256 interval); modifier onlyNotInitialized() { require(!initialized, "the wallet already initialized"); _; initialized = true; } modifier onlyInitialized() { require(initialized, "the wallet not init yet"); _; } function isSecuritySwitchOn() public view returns (bool) { return securitySwitch; } function getDeactivatedInterval() public view returns (uint256) { return deactivatedInterval; } function getLastActivatedTime() public view returns (uint256) { return lastActivatedTime; } } contract MultiSignWallet is WalletOwner, WalletSecurity { using SafeMath256 for uint256; event Deposit(address indexed from, uint256 value); event Transfer(address indexed token, address indexed to, uint256 value); event ExecuteWithData(address indexed token, uint256 value); event ExceptionTokenRemove(address indexed token); event ExceptionTokenAdd(address indexed token); modifier ensure(uint deadline) { require(deadline >= block.timestamp, "the wallet operation is expired"); _; } receive() external payable { if (msg.value > 0) { emit Deposit(msg.sender, msg.value); } } function initialize(address[] memory _owners, uint256 _required, bool _switchOn, uint256 _deactivatedInterval, address[] memory _exceptionTokens) external onlyNotInitialized returns(bool) { require(_required >= MIN_REQUIRED, "the signed owner count must than 1"); if (_switchOn) { require(_deactivatedInterval >= MIN_INACTIVE_INTERVAL, "inactive interval must more than 3days"); securitySwitch = _switchOn; deactivatedInterval = _deactivatedInterval; emit SecuritySwitchChange(securitySwitch, deactivatedInterval); } for (uint256 i = 0; i < _owners.length; i++) { if (_owners[i] == address(0x0)) { revert("the address can't be 0x"); } if (activeOwners[_owners[i]] > 0 ) { revert("the owners must be distinct"); } activeOwners[_owners[i]] = block.timestamp; emit OwnerAddition(_owners[i]); } require(_owners.length >= _required, "wallet owners must more than the required."); required = _required; emit SignRequirementChanged(required); owners = _owners; _updateActivatedTime(); if (_exceptionTokens.length > 0) { return _addExceptionToken(_exceptionTokens); } return true; } function addOwner(address[] memory _newOwners, uint256 _required, bytes32 salt, uint8[] memory vs, bytes32[] memory rs, bytes32[] memory ss, uint256 deadline) public onlyInitialized ensure(deadline) returns (bool) { require(_validOwnerAddParams(_newOwners, _required), "invalid params"); bytes32 message = SignMessage.ownerModifyMessage(address(this), getChainID(), _newOwners, _required, salt); require(getTransactionMessage(message) == 0, "transaction may has been excuted"); transactions[message] = block.number; require(_validSignature(message, vs, rs, ss), "invalid signatures"); address[] memory _oldOwners; return _updateOwners(_oldOwners, _newOwners, _required); } function removeOwner(address[] memory _oldOwners, uint256 _required, bytes32 salt, uint8[] memory vs, bytes32[] memory rs, bytes32[] memory ss, uint256 deadline) public onlyInitialized ensure(deadline) returns (bool) { require(_validOwnerRemoveParams(_oldOwners, _required), "invalid params"); bytes32 message = SignMessage.ownerModifyMessage(address(this), getChainID(), _oldOwners, _required, salt); require(getTransactionMessage(message) == 0, "transaction may has been excuted"); transactions[message] = block.timestamp; require(_validSignature(message, vs, rs, ss), "invalid signatures"); address[] memory _newOwners; return _updateOwners(_oldOwners, _newOwners, _required); } function replaceOwner(address[] memory _oldOwners, address[] memory _newOwners, uint256 _required, bytes32 salt, uint8[] memory vs, bytes32[] memory rs, bytes32[] memory ss, uint256 deadline) public onlyInitialized ensure(deadline) returns (bool) { require(_validOwnerReplaceParams(_oldOwners, _newOwners, _required), "invalid params"); bytes32 message = SignMessage.ownerReplaceMessage(address(this), getChainID(), _oldOwners, _newOwners, _required, salt); require(getTransactionMessage(message) == 0, "transaction may has been excuted"); transactions[message] = block.number; require(_validSignature(message, vs, rs, ss), "invalid signatures"); return _updateOwners(_oldOwners, _newOwners, _required); } function changeOwnerRequirement(uint256 _required, bytes32 salt, uint8[] memory vs, bytes32[] memory rs, bytes32[] memory ss, uint256 deadline) public onlyInitialized ensure(deadline) returns (bool) { require(_required >= MIN_REQUIRED, "the signed owner count must than 1"); require(owners.length >= _required, "the owners must more than the required"); bytes32 message = SignMessage.ownerRequiredMessage(address(this), getChainID(), _required, salt); require(getTransactionMessage(message) == 0, "transaction may has been excuted"); transactions[message] = block.number; require(_validSignature(message, vs, rs, ss), "invalid signatures"); required = _required; emit SignRequirementChanged(required); return true; } function changeSecurityParams(bool _switchOn, uint256 _deactivatedInterval, bytes32 salt, uint8[] memory vs, bytes32[] memory rs, bytes32[] memory ss, uint256 deadline) public onlyInitialized ensure(deadline) returns (bool) { bytes32 message = SignMessage.securitySwitchMessage(address(this), getChainID(), _switchOn, _deactivatedInterval, salt); require(getTransactionMessage(message) == 0, "transaction may has been excuted"); transactions[message] = block.number; require(_validSignature(message, vs, rs, ss), "invalid signatures"); if (_switchOn) { securitySwitch = true; require(_deactivatedInterval >= MIN_INACTIVE_INTERVAL, "inactive interval must more than 3days"); deactivatedInterval = _deactivatedInterval; } else { securitySwitch = false; deactivatedInterval = 0; } emit SecuritySwitchChange(_switchOn, deactivatedInterval); return true; } function transfer(address tokenAddress, address payable to, uint256 value, bytes32 salt, uint8[] memory vs, bytes32[] memory rs, bytes32[] memory ss, uint256 deadline) public onlyInitialized ensure(deadline) returns (bool) { if(tokenAddress == address(0x0)) { return _transferNativeToken(to, value, salt, vs, rs, ss); } return _transferContractToken(tokenAddress, to, value, salt, vs, rs, ss); } function execute(address contractAddress, uint256 value, bytes memory data, bytes32 salt, uint8[] memory vs, bytes32[] memory rs, bytes32[] memory ss, uint256 deadline) public onlyInitialized ensure(deadline) returns (bool) { require(contractAddress != address(this), "not allow transfer to yourself"); bytes32 message = SignMessage.executeWithDataMessage(address(this), getChainID(), contractAddress, value, salt, data); require(getTransactionMessage(message) == 0, "transaction may has been excuted"); transactions[message] = block.number; require(_validSignature(message, vs, rs, ss), "invalid signatures"); (bool success,) = contractAddress.call{value: value}(data); require(success, "contract execution Failed"); emit ExecuteWithData(contractAddress, value); return true; } function batchTransfer(address tokenAddress, address[] memory recipients, uint256[] memory amounts, bytes32 salt, uint8[] memory vs, bytes32[] memory rs, bytes32[] memory ss, uint256 deadline) public onlyInitialized ensure(deadline) returns (bool) { require(recipients.length > 0 && recipients.length == amounts.length, "parameters invalid"); bytes32 message = SignMessage.batchTransferMessage(address(this), getChainID(), tokenAddress, recipients, amounts, salt); require(getTransactionMessage(message) == 0, "transaction may has been excuted"); transactions[message] = block.number; require(_validSignature(message, vs, rs, ss), "invalid signatures"); for(uint256 i = 0; i < recipients.length; i++) { _transfer(tokenAddress, recipients[i], amounts[i]); emit Transfer(tokenAddress, recipients[i], amounts[i]); } return true; } function addExceptionToken(address[] memory tokens, bytes32 salt, uint8[] memory vs, bytes32[] memory rs, bytes32[] memory ss, uint256 deadline) public onlyInitialized ensure(deadline) returns (bool) { require(tokens.length > 0, "input tokens empty"); bytes32 message = SignMessage.modifyExceptionTokenMessage(address(this), getChainID(), tokens, salt); require(getTransactionMessage(message) == 0, "transaction may has been excuted"); transactions[message] = block.number; require(_validSignature(message, vs, rs, ss), "invalid signatures"); return _addExceptionToken(tokens); } function removeExceptionToken(address[] memory tokens, bytes32 salt, uint8[] memory vs, bytes32[] memory rs, bytes32[] memory ss, uint256 deadline) public onlyInitialized ensure(deadline) returns (bool) { require(tokens.length > 0, "input tokens empty"); bytes32 message = SignMessage.modifyExceptionTokenMessage(address(this), getChainID(), tokens, salt); require(getTransactionMessage(message) == 0, "transaction may has been excuted"); transactions[message] = block.number; require(_validSignature(message, vs, rs, ss), "invalid signatures"); return _removeExceptionToken(tokens); } function getChainID() public view returns (uint256) { uint256 id; assembly { id := chainid() } return id; } function getRequired() public view returns (uint256) { if(!securitySwitch) { return required; } uint256 _deactivate = block.timestamp; if (_deactivate <= lastActivatedTime + deactivatedInterval) { return required; } _deactivate = _deactivate.sub(lastActivatedTime).sub(deactivatedInterval).div(securityInterval); if (required > _deactivate) { return required.sub(_deactivate); } return MIN_REQUIRED; } function getTransactionMessage(bytes32 message) public view returns (uint256) { return transactions[message]; } function isExceptionToken(address token) public view returns (bool) { return exceptionTokens[token] != 0; } function _transferContractToken(address tokenAddress, address to, uint256 value, bytes32 salt, uint8[] memory vs, bytes32[] memory rs, bytes32[] memory ss) internal returns (bool) { require(to != address(this), "not allow transfer to yourself"); require(value > 0, "transfer value must more than 0"); bytes32 message = SignMessage.transferMessage(address(this), getChainID(), tokenAddress, to, value, salt); require(getTransactionMessage(message) == 0, "transaction may has been excuted"); transactions[message] = block.number; require(_validSignature(message, vs, rs, ss), "invalid signatures"); _safeTransfer(tokenAddress, to, value); emit Transfer(tokenAddress, to, value); return true; } function _transferNativeToken(address payable to, uint256 value, bytes32 salt, uint8[] memory vs, bytes32[] memory rs, bytes32[] memory ss) internal returns (bool) { require(to != address(this), "not allow transfer to yourself"); require(value > 0, "transfer value must more than 0"); require(address(this).balance >= value, "balance not enough"); bytes32 message = SignMessage.transferMessage(address(this), getChainID(), address(0x0), to, value, salt); require(getTransactionMessage(message) == 0, "transaction may has been excuted"); transactions[message] = block.number; require(_validSignature(message, vs, rs, ss), "invalid signatures"); _safeTransferNative(to, value); emit Transfer(address(0x0), to, value); return true; } function _transfer(address tokenAddress, address recipient, uint256 value) internal { require(value > 0, "transfer value must more than 0"); require(recipient != address(this), "not allow transfer to yourself"); if (tokenAddress == address(0x0)) { _safeTransferNative(recipient, value); return; } _safeTransfer(tokenAddress, recipient, value); } function _updateActivatedTime() internal { lastActivatedTime = block.timestamp; } function _addExceptionToken(address[] memory tokens) internal returns(bool) { for(uint256 i = 0; i < tokens.length; i++) { if(!isExceptionToken(tokens[i])) { require(tokens[i] != address(0x0), "the token address can't be 0x"); exceptionTokens[tokens[i]] = block.number; emit ExceptionTokenAdd(tokens[i]); } } return true; } function _removeExceptionToken(address[] memory tokens) internal returns(bool) { for(uint256 i = 0; i < tokens.length; i++) { if(isExceptionToken(tokens[i])) { require(tokens[i] != address(0x0), "the token address can't be 0x"); exceptionTokens[tokens[i]] = 0; emit ExceptionTokenRemove(tokens[i]); } } return true; } function _validOwnerAddParams(address[] memory _owners, uint256 _required) private view returns (bool) { require(_owners.length > 0, "the new owners list can't be emtpy"); require(_required >= MIN_REQUIRED, "the signed owner count must than 1"); uint256 ownerCount = _owners.length; ownerCount = ownerCount.add(owners.length); require(ownerCount >= _required, "the owner count must more than the required"); return _distinctAddOwners(_owners); } function _validOwnerRemoveParams(address[] memory _owners, uint256 _required) private view returns (bool) { require(_owners.length > 0 && _required >= MIN_REQUIRED, "invalid parameters"); uint256 ownerCount = owners.length; ownerCount = ownerCount.sub(_owners.length); require(ownerCount >= _required, "the owners must more than the required"); return _distinctRemoveOwners(_owners); } function _validOwnerReplaceParams(address[] memory _oldOwners, address[] memory _newOwners, uint256 _required) private view returns (bool) { require(_oldOwners.length >0 || _newOwners.length > 0, "the two input owner list can't both be empty"); require(_required >= MIN_REQUIRED, "the signed owner's count must than 1"); _distinctRemoveOwners(_oldOwners); _distinctAddOwners(_newOwners); uint256 ownerCount = owners.length; ownerCount = ownerCount.add(_newOwners.length).sub(_oldOwners.length); require(ownerCount >= _required, "the owner's count must more than the required"); return true; } function _distinctRemoveOwners(address[] memory _owners) private view returns (bool) { for(uint256 i = 0; i < _owners.length; i++) { if (_owners[i] == address(0x0)) { revert("the remove address can't be 0x."); } if(activeOwners[_owners[i]] == 0) { revert("the remove address must be a owner."); } for(uint256 j = 0; j < i; j++) { if(_owners[j] == _owners[i]) { revert("the remove address must be distinct"); } } } return true; } function _distinctAddOwners(address[] memory _owners) private view returns (bool) { for(uint256 i = 0; i < _owners.length; i++) { if (_owners[i] == address(0x0)) { revert("the new address can't be 0x."); } if (activeOwners[_owners[i]] != 0) { revert("the new address is already a owner"); } for(uint256 j = 0; j < i; j++) { if(_owners[j] == _owners[i]) { revert("the new address must be distinct"); } } } return true; } function _validSignature(bytes32 recoverMsg, uint8[] memory vs, bytes32[] memory rs, bytes32[] memory ss) private returns (bool) { require(vs.length == rs.length); require(rs.length == ss.length); require(vs.length <= owners.length); require(vs.length >= getRequired()); address[] memory signedAddresses = new address[](vs.length); for (uint256 i = 0; i < vs.length; i++) { signedAddresses[i] = ecrecover(recoverMsg, vs[i]+27, rs[i], ss[i]); } require(_distinctSignedOwners(signedAddresses), "signed owner must be distinct"); _updateActiveOwners(signedAddresses); _updateActivatedTime(); return true; } function _updateOwners(address[] memory _oldOwners, address[] memory _newOwners, uint256 _required) private returns (bool) { for(uint256 i = 0; i < _oldOwners.length; i++) { for (uint256 j = 0; j < owners.length; j++) { if (owners[j] == _oldOwners[i]) { activeOwners[owners[j]] = 0; owners[j] = owners[owners.length - 1]; owners.pop(); emit OwnerRemoval(_oldOwners[i]); break; } } } for(uint256 i = 0; i < _newOwners.length; i++) { owners.push(_newOwners[i]); activeOwners[_newOwners[i]] = block.timestamp; emit OwnerAddition(_newOwners[i]); } require(owners.length >= _required, "the owners must more than the required"); required = _required; emit SignRequirementChanged(required); return true; } function _updateActiveOwners(address[] memory _owners) private returns (bool){ for (uint256 i = 0; i < _owners.length; i++) { activeOwners[_owners[i]] = block.timestamp; } return true; } function _distinctSignedOwners(address[] memory _owners) private view returns (bool) { if (_owners.length > owners.length) { return false; } for (uint256 i = 0; i < _owners.length; i++) { if(activeOwners[_owners[i]] == 0) { return false; } for (uint256 j = 0; j < i; j++) { if(_owners[j] == _owners[i]) { return false; } } } return true; } function _safeTransfer(address token, address recipient, uint256 value) internal { if(isExceptionToken(token)) { (bool success, ) = token.call(abi.encodeWithSelector(IERC20(token).transfer.selector, recipient, value)); require(success, "ERC20 transfer failed"); return; } SafeERC20.safeTransfer(IERC20(token), recipient, value); } function _safeTransferNative(address recipient, uint256 value) internal { (bool success,) = recipient.call{value:value}(new bytes(0)); require(success, "transfer native failed"); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.0; import "./MultiSignWallet.sol"; import "./IMultiSignWalletFactory.sol"; contract MultiSignWalletProxy { address immutable private walletFactory; constructor() { walletFactory = msg.sender; } receive() external payable {} fallback() external { address impl = IMultiSignWalletFactory(walletFactory).getWalletImpl(); assembly { let ptr := mload(0x40) let size := calldatasize() calldatacopy(ptr, 0, size) let result := delegatecall(gas(), impl, ptr, size, 0, 0) size := returndatasize() returndatacopy(ptr, 0, size) switch result case 0 { revert(ptr, size) } default { return(ptr, size) } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "./IERC20.sol"; import "./Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.0; library SafeMath256 { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.0; library SignMessage { function transferMessage(address wallet, uint256 chainID, address tokenAddress, address to, uint256 value, bytes32 salt) internal pure returns (bytes32) { bytes32 message = keccak256(abi.encodePacked(wallet, chainID, tokenAddress, to, value, salt)); return messageToSign(message); } function executeWithDataMessage(address wallet, uint256 chainID, address contractAddress, uint256 value, bytes32 salt, bytes memory data) internal pure returns (bytes32) { bytes32 message = keccak256(abi.encodePacked(wallet, chainID, contractAddress, value, salt, data)); return messageToSign(message); } function batchTransferMessage(address wallet, uint256 chainID, address tokenAddress, address[] memory recipients, uint256[] memory amounts, bytes32 salt) internal pure returns (bytes32) { bytes32 message = keccak256(abi.encodePacked(wallet, chainID, tokenAddress, recipients, amounts, salt)); return messageToSign(message); } function ownerReplaceMessage(address wallet, uint256 chainID, address[] memory _oldOwners, address[] memory _newOwners, uint256 _required, bytes32 salt) internal pure returns (bytes32) { bytes32 message = keccak256(abi.encodePacked(wallet, chainID, _oldOwners, _newOwners, _required, salt)); return messageToSign(message); } function ownerModifyMessage(address wallet, uint256 chainID, address[] memory _owners, uint256 _required, bytes32 salt) internal pure returns (bytes32) { bytes32 message = keccak256(abi.encodePacked(wallet, chainID, _owners, _required, salt)); return messageToSign(message); } function ownerRequiredMessage(address wallet, uint256 chainID, uint256 _required, bytes32 salt) internal pure returns (bytes32) { bytes32 message = keccak256(abi.encodePacked(wallet, chainID, _required, salt)); return messageToSign(message); } function securitySwitchMessage(address wallet, uint256 chainID, bool swithOn, uint256 _deactivatedInterval, bytes32 salt) internal pure returns (bytes32) { bytes32 message = keccak256(abi.encodePacked(wallet, chainID, swithOn, _deactivatedInterval, salt)); return messageToSign(message); } function modifyExceptionTokenMessage(address wallet, uint256 chainID, address[] memory _tokens, bytes32 salt) internal pure returns (bytes32) { bytes32 message = keccak256(abi.encodePacked(wallet, chainID, _tokens, salt)); return messageToSign(message); } function messageToSign(bytes32 message) internal pure returns (bytes32) { bytes memory prefix = "\x19Ethereum Signed Message:\n32"; return keccak256(abi.encodePacked(prefix, message)); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address payable","name":"_walletImpl","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"wallet","type":"address"}],"name":"NewWallet","type":"event"},{"inputs":[{"internalType":"address[]","name":"_owners","type":"address[]"},{"internalType":"uint256","name":"_required","type":"uint256"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"bool","name":"_securitySwitch","type":"bool"},{"internalType":"uint256","name":"_inactiveInterval","type":"uint256"},{"internalType":"address[]","name":"_execptionTokens","type":"address[]"}],"name":"create","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getWalletImpl","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a060405234801561001057600080fd5b506040516106b23803806106b283398101604081905261002f91610044565b60601b6001600160601b031916608052610072565b600060208284031215610055578081fd5b81516001600160a01b038116811461006b578182fd5b9392505050565b60805160601c61062361008f6000396000606e01526106236000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806334c5c27e1461003b578063853b559e14610059575b600080fd5b61004361006c565b60405161005091906103bc565b60405180910390f35b610043610067366004610276565b610090565b7f000000000000000000000000000000000000000000000000000000000000000090565b600080866040516100a090610220565b8190604051809103906000f59050801580156100c0573d6000803e3d6000fd5b509050600080826001600160a01b03166040518060600160405280603481526020016105ba60349139805190602001208d8d8d8c8c8c8c60405160240161010d97969594939291906103d0565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161014b9190610383565b6000604051808303816000865af19150503d8060008114610188576040519150601f19603f3d011682016040523d82523d6000602084013e61018d565b606091505b50915091508180156101b75750805115806101b75750808060200190518101906101b79190610314565b6101dc5760405162461bcd60e51b81526004016101d390610419565b60405180910390fd5b6040516001600160a01b038416907fd627a1aeb13261b560c345aaf7d003d55a27193b9284c0b941f53cd62a045f1690600090a250909a9950505050505050505050565b6101618061045983390190565b60008083601f84011261023e578182fd5b50813567ffffffffffffffff811115610255578182fd5b602083019150836020808302850101111561026f57600080fd5b9250929050565b60008060008060008060008060c0898b031215610291578384fd5b883567ffffffffffffffff808211156102a8578586fd5b6102b48c838d0161022d565b909a50985060208b0135975060408b0135965060608b013591506102d782610447565b90945060808a0135935060a08a013590808211156102f3578384fd5b506103008b828c0161022d565b999c989b5096995094979396929594505050565b600060208284031215610325578081fd5b815161033081610447565b9392505050565b60008284526020808501945082825b858110156103785781356001600160a01b038116808214610365578586fd5b8852509582019590820190600101610346565b509495945050505050565b60008251815b818110156103a35760208186018101518583015201610389565b818111156103b15782828501525b509190910192915050565b6001600160a01b0391909116815260200190565b600060a082526103e460a08301898b610337565b8760208401528615156040840152856060840152828103608084015261040b818587610337565b9a9950505050505050505050565b60208082526014908201527318dc99585d19481dd85b1b195d0819985a5b195960621b604082015260600190565b801515811461045557600080fd5b5056fe60a060405234801561001057600080fd5b5033606081901b6080526101306100316000396000601a01526101306000f3fe608060405236600a57005b348015601557600080fd5b5060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166334c5c27e6040518163ffffffff1660e01b815260040160206040518083038186803b158015607057600080fd5b505afa1580156083573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019060a5919060ce565b90506040513680600083376000808284865af43d9150816000843e80801560ca578284f35b8284fd5b60006020828403121560de578081fd5b81516001600160a01b038116811460f3578182fd5b939250505056fea26469706673582212202d7455c5aef8e419d6ee3792cdbc3ca778174bf6a996b54541842f509ae9d0cb64736f6c63430008000033696e697469616c697a6528616464726573735b5d2c75696e743235362c626f6f6c2c75696e743235362c616464726573735b5d29a2646970667358221220127a66ea1fb914b2421d4b092408b4ca81317e9d00b3e401c9a34e77c228ebf564736f6c63430008000033000000000000000000000000a3d5699a389c1be44468add10134cb33f726d391
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100365760003560e01c806334c5c27e1461003b578063853b559e14610059575b600080fd5b61004361006c565b60405161005091906103bc565b60405180910390f35b610043610067366004610276565b610090565b7f000000000000000000000000a3d5699a389c1be44468add10134cb33f726d39190565b600080866040516100a090610220565b8190604051809103906000f59050801580156100c0573d6000803e3d6000fd5b509050600080826001600160a01b03166040518060600160405280603481526020016105ba60349139805190602001208d8d8d8c8c8c8c60405160240161010d97969594939291906103d0565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161014b9190610383565b6000604051808303816000865af19150503d8060008114610188576040519150601f19603f3d011682016040523d82523d6000602084013e61018d565b606091505b50915091508180156101b75750805115806101b75750808060200190518101906101b79190610314565b6101dc5760405162461bcd60e51b81526004016101d390610419565b60405180910390fd5b6040516001600160a01b038416907fd627a1aeb13261b560c345aaf7d003d55a27193b9284c0b941f53cd62a045f1690600090a250909a9950505050505050505050565b6101618061045983390190565b60008083601f84011261023e578182fd5b50813567ffffffffffffffff811115610255578182fd5b602083019150836020808302850101111561026f57600080fd5b9250929050565b60008060008060008060008060c0898b031215610291578384fd5b883567ffffffffffffffff808211156102a8578586fd5b6102b48c838d0161022d565b909a50985060208b0135975060408b0135965060608b013591506102d782610447565b90945060808a0135935060a08a013590808211156102f3578384fd5b506103008b828c0161022d565b999c989b5096995094979396929594505050565b600060208284031215610325578081fd5b815161033081610447565b9392505050565b60008284526020808501945082825b858110156103785781356001600160a01b038116808214610365578586fd5b8852509582019590820190600101610346565b509495945050505050565b60008251815b818110156103a35760208186018101518583015201610389565b818111156103b15782828501525b509190910192915050565b6001600160a01b0391909116815260200190565b600060a082526103e460a08301898b610337565b8760208401528615156040840152856060840152828103608084015261040b818587610337565b9a9950505050505050505050565b60208082526014908201527318dc99585d19481dd85b1b195d0819985a5b195960621b604082015260600190565b801515811461045557600080fd5b5056fe60a060405234801561001057600080fd5b5033606081901b6080526101306100316000396000601a01526101306000f3fe608060405236600a57005b348015601557600080fd5b5060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166334c5c27e6040518163ffffffff1660e01b815260040160206040518083038186803b158015607057600080fd5b505afa1580156083573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019060a5919060ce565b90506040513680600083376000808284865af43d9150816000843e80801560ca578284f35b8284fd5b60006020828403121560de578081fd5b81516001600160a01b038116811460f3578182fd5b939250505056fea26469706673582212202d7455c5aef8e419d6ee3792cdbc3ca778174bf6a996b54541842f509ae9d0cb64736f6c63430008000033696e697469616c697a6528616464726573735b5d2c75696e743235362c626f6f6c2c75696e743235362c616464726573735b5d29a2646970667358221220127a66ea1fb914b2421d4b092408b4ca81317e9d00b3e401c9a34e77c228ebf564736f6c63430008000033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000A3d5699a389c1be44468AdD10134CB33F726d391
-----Decoded View---------------
Arg [0] : _walletImpl (address): 0xA3d5699a389c1be44468AdD10134CB33F726d391
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000A3d5699a389c1be44468AdD10134CB33F726d391
Deployed Bytecode Sourcemap
136:1097:4:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1132:99;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;509:617;;;;;;:::i;:::-;;:::i;1132:99::-;1214:10;1132:99;:::o;509:617::-;682:7;701:27;762:4;731:38;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;701:68;;780:12;794:17;823:6;-1:-1:-1;;;;;815:20:4;352:61;;;;;;;;;;;;;;;;;342:72;;;;;;872:7;;881:9;892:15;909:17;928:16;;836:109;;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;836:109:4;;;;;;;;;;;;;;-1:-1:-1;;;;;836:109:4;-1:-1:-1;;;;;;836:109:4;;;;;;;;;;815:131;;;;836:109;815:131;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;779:167;;;;964:7;:57;;;;-1:-1:-1;976:11:4;;:16;;:44;;;1007:4;996:24;;;;;;;;;;;;:::i;:::-;956:90;;;;-1:-1:-1;;;956:90:4;;;;;;;:::i;:::-;;;;;;;;;1061:26;;-1:-1:-1;;;;;1061:26:4;;;;;;;;-1:-1:-1;1112:6:4;;509:617;-1:-1:-1;;;;;;;;;;509:617:4:o;-1:-1:-1:-;;;;;;;;:::o;14:404:9:-;;;147:3;140:4;132:6;128:17;124:27;114:2;;172:8;162;155:26;114:2;-1:-1:-1;202:20:9;;245:18;234:30;;231:2;;;284:8;274;267:26;231:2;328:4;320:6;316:17;304:29;;391:3;384:4;376;368:6;364:17;356:6;352:30;348:41;345:50;342:2;;;408:1;405;398:12;342:2;104:314;;;;;:::o;423:1153::-;;;;;;;;;687:3;675:9;666:7;662:23;658:33;655:2;;;709:6;701;694:22;655:2;754:9;741:23;783:18;824:2;816:6;813:14;810:2;;;845:6;837;830:22;810:2;889:76;957:7;948:6;937:9;933:22;889:76;:::i;:::-;984:8;;-1:-1:-1;863:102:9;-1:-1:-1;1066:2:9;1051:18;;1038:32;;-1:-1:-1;1117:2:9;1102:18;;1089:32;;-1:-1:-1;1171:2:9;1156:18;;1143:32;;-1:-1:-1;1184:30:9;1143:32;1184:30;:::i;:::-;1233:5;;-1:-1:-1;1285:3:9;1270:19;;1257:33;;-1:-1:-1;1343:3:9;1328:19;;1315:33;;1360:16;;;1357:2;;;1394:6;1386;1379:22;1357:2;;1438:78;1508:7;1497:8;1486:9;1482:24;1438:78;:::i;:::-;645:931;;;;-1:-1:-1;645:931:9;;-1:-1:-1;645:931:9;;;;;;1535:8;-1:-1:-1;;;645:931:9:o;1581:257::-;;1701:2;1689:9;1680:7;1676:23;1672:32;1669:2;;;1722:6;1714;1707:22;1669:2;1759:9;1753:16;1778:30;1802:5;1778:30;:::i;:::-;1827:5;1659:179;-1:-1:-1;;;1659:179:9:o;1843:569::-;;1949:6;1944:3;1937:19;1975:4;2004:2;1999:3;1995:12;1988:19;;2030:5;2053:3;2065:322;2079:6;2076:1;2073:13;2065:322;;;2143:20;;-1:-1:-1;;;;;2186:33:9;;2242:15;;;2232:2;;2273:3;2268;2261:16;2232:2;2292:15;;-1:-1:-1;2327:12:9;;;;2362:15;;;;2101:1;2094:9;2065:322;;;-1:-1:-1;2403:3:9;;1927:485;-1:-1:-1;;;;;1927:485:9:o;2417:430::-;;2584:6;2578:13;2609:3;2621:129;2635:6;2632:1;2629:13;2621:129;;;2733:4;2717:14;;;2713:25;;2707:32;2694:11;;;2687:53;2650:12;2621:129;;;2768:6;2765:1;2762:13;2759:2;;;2803:3;2794:6;2789:3;2785:16;2778:29;2759:2;-1:-1:-1;2825:16:9;;;;;2554:293;-1:-1:-1;;2554:293:9:o;2852:203::-;-1:-1:-1;;;;;3016:32:9;;;;2998:51;;2986:2;2971:18;;2953:102::o;3060:757::-;;3415:3;3404:9;3397:22;3442:80;3517:3;3506:9;3502:19;3494:6;3486;3442:80;:::i;:::-;3558:6;3553:2;3542:9;3538:18;3531:34;3615:6;3608:14;3601:22;3596:2;3585:9;3581:18;3574:50;3660:6;3655:2;3644:9;3640:18;3633:34;3716:9;3708:6;3704:22;3698:3;3687:9;3683:19;3676:51;3744:67;3804:6;3796;3788;3744:67;:::i;:::-;3736:75;3387:430;-1:-1:-1;;;;;;;;;;3387:430:9:o;3822:344::-;4024:2;4006:21;;;4063:2;4043:18;;;4036:30;-1:-1:-1;;;4097:2:9;4082:18;;4075:50;4157:2;4142:18;;3996:170::o;4171:120::-;4259:5;4252:13;4245:21;4238:5;4235:32;4225:2;;4281:1;4278;4271:12;4225:2;4215:76;:::o
Swarm Source
ipfs://127a66ea1fb914b2421d4b092408b4ca81317e9d00b3e401c9a34e77c228ebf5
Loading...
Loading
Loading...
Loading
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.