More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 19,080 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Process Exits | 21275410 | 50 mins ago | IN | 0 ETH | 0.00185852 | ||||
Process Exits | 21273362 | 7 hrs ago | IN | 0 ETH | 0.00199232 | ||||
Process Exits | 21273278 | 7 hrs ago | IN | 0 ETH | 0.00054047 | ||||
Process Exits | 21273275 | 7 hrs ago | IN | 0 ETH | 0.00051447 | ||||
Process Exits | 21273272 | 7 hrs ago | IN | 0 ETH | 0.00050748 | ||||
Process Exits | 21273130 | 8 hrs ago | IN | 0 ETH | 0.00052082 | ||||
Process Exits | 21273127 | 8 hrs ago | IN | 0 ETH | 0.00051754 | ||||
Process Exits | 21273123 | 8 hrs ago | IN | 0 ETH | 0.00234755 | ||||
Process Exits | 21272527 | 10 hrs ago | IN | 0 ETH | 0.00288564 | ||||
Process Exits | 21271923 | 12 hrs ago | IN | 0 ETH | 0.00206244 | ||||
Process Exits | 21270941 | 15 hrs ago | IN | 0 ETH | 0.0014832 | ||||
Process Exits | 21269747 | 19 hrs ago | IN | 0 ETH | 0.00102677 | ||||
Process Exits | 21266835 | 29 hrs ago | IN | 0 ETH | 0.00270911 | ||||
Process Exits | 21265070 | 35 hrs ago | IN | 0 ETH | 0.00296554 | ||||
Process Exits | 21263572 | 40 hrs ago | IN | 0 ETH | 0.00105252 | ||||
Process Exits | 21263240 | 41 hrs ago | IN | 0 ETH | 0.00095673 | ||||
Process Exits | 21262218 | 45 hrs ago | IN | 0 ETH | 0.00124651 | ||||
Process Exits | 21260206 | 2 days ago | IN | 0 ETH | 0.00179725 | ||||
Process Exits | 21259076 | 2 days ago | IN | 0 ETH | 0.00206289 | ||||
Process Exits | 21255871 | 2 days ago | IN | 0 ETH | 0.00130882 | ||||
Process Exits | 21255615 | 2 days ago | IN | 0 ETH | 0.00032086 | ||||
Process Exits | 21255615 | 2 days ago | IN | 0 ETH | 0.00262145 | ||||
Process Exits | 21254620 | 2 days ago | IN | 0 ETH | 0.00116421 | ||||
Process Exits | 21254488 | 2 days ago | IN | 0 ETH | 0.00039772 | ||||
Process Exits | 21254488 | 2 days ago | IN | 0 ETH | 0.00247244 |
Latest 10 internal transactions
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
20678430 | 83 days ago | Contract Creation | 0 ETH | |||
16995286 | 599 days ago | 0.03211642 ETH | ||||
16380339 | 685 days ago | 0.02993631 ETH | ||||
10614742 | 1572 days ago | Contract Creation | 0 ETH | |||
10599655 | 1574 days ago | Contract Creation | 0 ETH | |||
10539932 | 1583 days ago | Contract Creation | 0 ETH | |||
10168409 | 1641 days ago | Contract Creation | 0 ETH | |||
10168396 | 1641 days ago | Contract Creation | 0 ETH | |||
10168396 | 1641 days ago | Contract Creation | 0 ETH | |||
10168395 | 1641 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Name:
WithdrawManagerProxy
Compiler Version
v0.5.11+commit.c082d0b4
Optimization Enabled:
Yes with 200 runs
Other Settings:
constantinople EvmVersion, GNU GPLv2 license
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2020-05-31 */ // File: contracts/common/governance/IGovernance.sol pragma solidity ^0.5.2; interface IGovernance { function update(address target, bytes calldata data) external; } // File: contracts/common/governance/Governable.sol pragma solidity ^0.5.2; contract Governable { IGovernance public governance; constructor(address _governance) public { governance = IGovernance(_governance); } modifier onlyGovernance() { require(msg.sender == address(governance), "Only governance contract is authorized"); _; } } // File: contracts/root/withdrawManager/IWithdrawManager.sol pragma solidity ^0.5.2; contract IWithdrawManager { function createExitQueue(address token) external; function verifyInclusion( bytes calldata data, uint8 offset, bool verifyTxInclusion ) external view returns (uint256 age); function addExitToQueue( address exitor, address childToken, address rootToken, uint256 exitAmountOrTokenId, bytes32 txHash, bool isRegularExit, uint256 priority ) external; function addInput( uint256 exitId, uint256 age, address utxoOwner, address token ) external; function challengeExit( uint256 exitId, uint256 inputId, bytes calldata challengeData, address adjudicatorPredicate ) external; } // File: contracts/common/Registry.sol pragma solidity ^0.5.2; contract Registry is Governable { // @todo hardcode constants bytes32 private constant WETH_TOKEN = keccak256("wethToken"); bytes32 private constant DEPOSIT_MANAGER = keccak256("depositManager"); bytes32 private constant STAKE_MANAGER = keccak256("stakeManager"); bytes32 private constant VALIDATOR_SHARE = keccak256("validatorShare"); bytes32 private constant WITHDRAW_MANAGER = keccak256("withdrawManager"); bytes32 private constant CHILD_CHAIN = keccak256("childChain"); bytes32 private constant STATE_SENDER = keccak256("stateSender"); bytes32 private constant SLASHING_MANAGER = keccak256("slashingManager"); address public erc20Predicate; address public erc721Predicate; mapping(bytes32 => address) public contractMap; mapping(address => address) public rootToChildToken; mapping(address => address) public childToRootToken; mapping(address => bool) public proofValidatorContracts; mapping(address => bool) public isERC721; enum Type {Invalid, ERC20, ERC721, Custom} struct Predicate { Type _type; } mapping(address => Predicate) public predicates; event TokenMapped(address indexed rootToken, address indexed childToken); event ProofValidatorAdded(address indexed validator, address indexed from); event ProofValidatorRemoved(address indexed validator, address indexed from); event PredicateAdded(address indexed predicate, address indexed from); event PredicateRemoved(address indexed predicate, address indexed from); event ContractMapUpdated(bytes32 indexed key, address indexed previousContract, address indexed newContract); constructor(address _governance) public Governable(_governance) {} function updateContractMap(bytes32 _key, address _address) external onlyGovernance { emit ContractMapUpdated(_key, contractMap[_key], _address); contractMap[_key] = _address; } /** * @dev Map root token to child token * @param _rootToken Token address on the root chain * @param _childToken Token address on the child chain * @param _isERC721 Is the token being mapped ERC721 */ function mapToken( address _rootToken, address _childToken, bool _isERC721 ) external onlyGovernance { require(_rootToken != address(0x0) && _childToken != address(0x0), "INVALID_TOKEN_ADDRESS"); rootToChildToken[_rootToken] = _childToken; childToRootToken[_childToken] = _rootToken; isERC721[_rootToken] = _isERC721; IWithdrawManager(contractMap[WITHDRAW_MANAGER]).createExitQueue(_rootToken); emit TokenMapped(_rootToken, _childToken); } function addErc20Predicate(address predicate) public onlyGovernance { require(predicate != address(0x0), "Can not add null address as predicate"); erc20Predicate = predicate; addPredicate(predicate, Type.ERC20); } function addErc721Predicate(address predicate) public onlyGovernance { erc721Predicate = predicate; addPredicate(predicate, Type.ERC721); } function addPredicate(address predicate, Type _type) public onlyGovernance { require(predicates[predicate]._type == Type.Invalid, "Predicate already added"); predicates[predicate]._type = _type; emit PredicateAdded(predicate, msg.sender); } function removePredicate(address predicate) public onlyGovernance { require(predicates[predicate]._type != Type.Invalid, "Predicate does not exist"); delete predicates[predicate]; emit PredicateRemoved(predicate, msg.sender); } function getValidatorShareAddress() public view returns (address) { return contractMap[VALIDATOR_SHARE]; } function getWethTokenAddress() public view returns (address) { return contractMap[WETH_TOKEN]; } function getDepositManagerAddress() public view returns (address) { return contractMap[DEPOSIT_MANAGER]; } function getStakeManagerAddress() public view returns (address) { return contractMap[STAKE_MANAGER]; } function getSlashingManagerAddress() public view returns (address) { return contractMap[SLASHING_MANAGER]; } function getWithdrawManagerAddress() public view returns (address) { return contractMap[WITHDRAW_MANAGER]; } function getChildChainAndStateSender() public view returns (address, address) { return (contractMap[CHILD_CHAIN], contractMap[STATE_SENDER]); } function isTokenMapped(address _token) public view returns (bool) { return rootToChildToken[_token] != address(0x0); } function isTokenMappedAndIsErc721(address _token) public view returns (bool) { require(isTokenMapped(_token), "TOKEN_NOT_MAPPED"); return isERC721[_token]; } function isTokenMappedAndGetPredicate(address _token) public view returns (address) { if (isTokenMappedAndIsErc721(_token)) { return erc721Predicate; } return erc20Predicate; } function isChildTokenErc721(address childToken) public view returns (bool) { address rootToken = childToRootToken[childToken]; require(rootToken != address(0x0), "Child token is not mapped"); return isERC721[rootToken]; } } // File: openzeppelin-solidity/contracts/ownership/Ownable.sol pragma solidity ^0.5.2; /** * @title Ownable * @dev The Ownable contract has an owner address, and provides basic authorization control * functions, this simplifies the implementation of "user permissions". */ contract Ownable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev The Ownable constructor sets the original `owner` of the contract to the sender * account. */ constructor() internal { _owner = msg.sender; emit OwnershipTransferred(address(0), _owner); } /** * @return the address of the owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(isOwner()); _; } /** * @return true if `msg.sender` is the owner of the contract. */ function isOwner() public view returns (bool) { return msg.sender == _owner; } /** * @dev Allows the current owner to relinquish control of the contract. * It will not be possible to call the functions with the `onlyOwner` * modifier anymore. * @notice Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Allows the current owner to transfer control of the contract to a newOwner. * @param newOwner The address to transfer ownership to. */ function transferOwnership(address newOwner) public onlyOwner { _transferOwnership(newOwner); } /** * @dev Transfers control of the contract to a newOwner. * @param newOwner The address to transfer ownership to. */ function _transferOwnership(address newOwner) internal { require(newOwner != address(0)); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } // File: contracts/common/misc/ProxyStorage.sol pragma solidity ^0.5.2; contract ProxyStorage is Ownable { address internal proxyTo; } // File: contracts/common/misc/ERCProxy.sol /* * SPDX-License-Identitifer: MIT */ pragma solidity ^0.5.2; // See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-897.md interface ERCProxy { function proxyType() external pure returns (uint256 proxyTypeId); function implementation() external view returns (address codeAddr); } // File: contracts/common/misc/DelegateProxy.sol pragma solidity ^0.5.2; contract DelegateProxy is ERCProxy { function proxyType() external pure returns (uint256 proxyTypeId) { // Upgradeable proxy proxyTypeId = 2; } function implementation() external view returns (address); function delegatedFwd(address _dst, bytes memory _calldata) internal { // solium-disable-next-line security/no-inline-assembly assembly { let result := delegatecall(sub(gas, 10000), _dst, add(_calldata, 0x20), mload(_calldata), 0, 0) let size := returndatasize let ptr := mload(0x40) returndatacopy(ptr, 0, size) // revert instead of invalid() bc if the underlying call failed with invalid() it already wasted gas. // if the call returned error data, forward it switch result case 0 { revert(ptr, size) } default { return(ptr, size) } } } } // File: contracts/common/misc/Proxy.sol pragma solidity ^0.5.2; contract Proxy is ProxyStorage, DelegateProxy { event ProxyUpdated(address indexed _new, address indexed _old); event OwnerUpdate(address _prevOwner, address _newOwner); constructor(address _proxyTo) public { updateImplementation(_proxyTo); } function() external payable { // require(currentContract != 0, "If app code has not been set yet, do not call"); // Todo: filter out some calls or handle in the end fallback delegatedFwd(proxyTo, msg.data); } function implementation() external view returns (address) { return proxyTo; } function updateImplementation(address _newProxyTo) public onlyOwner { require(_newProxyTo != address(0x0), "INVALID_PROXY_ADDRESS"); require(isContract(_newProxyTo), "DESTINATION_ADDRESS_IS_NOT_A_CONTRACT"); emit ProxyUpdated(_newProxyTo, proxyTo); proxyTo = _newProxyTo; } function isContract(address _target) internal view returns (bool) { if (_target == address(0)) { return false; } uint256 size; assembly { size := extcodesize(_target) } return size > 0; } } // File: solidity-rlp/contracts/RLPReader.sol /* * @author Hamdi Allam [email protected] * Please reach out with any questions or concerns */ pragma solidity ^0.5.0; library RLPReader { uint8 constant STRING_SHORT_START = 0x80; uint8 constant STRING_LONG_START = 0xb8; uint8 constant LIST_SHORT_START = 0xc0; uint8 constant LIST_LONG_START = 0xf8; uint8 constant WORD_SIZE = 32; struct RLPItem { uint256 len; uint256 memPtr; } struct Iterator { RLPItem item; // Item that's being iterated over. uint256 nextPtr; // Position of the next item in the list. } /* * @dev Returns the next element in the iteration. Reverts if it has not next element. * @param self The iterator. * @return The next element in the iteration. */ function next(Iterator memory self) internal pure returns (RLPItem memory) { require(hasNext(self)); uint256 ptr = self.nextPtr; uint256 itemLength = _itemLength(ptr); self.nextPtr = ptr + itemLength; return RLPItem(itemLength, ptr); } /* * @dev Returns true if the iteration has more elements. * @param self The iterator. * @return true if the iteration has more elements. */ function hasNext(Iterator memory self) internal pure returns (bool) { RLPItem memory item = self.item; return self.nextPtr < item.memPtr + item.len; } /* * @param item RLP encoded bytes */ function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) { uint256 memPtr; assembly { memPtr := add(item, 0x20) } return RLPItem(item.length, memPtr); } /* * @dev Create an iterator. Reverts if item is not a list. * @param self The RLP item. * @return An 'Iterator' over the item. */ function iterator(RLPItem memory self) internal pure returns (Iterator memory) { require(isList(self)); uint256 ptr = self.memPtr + _payloadOffset(self.memPtr); return Iterator(self, ptr); } /* * @param item RLP encoded bytes */ function rlpLen(RLPItem memory item) internal pure returns (uint256) { return item.len; } /* * @param item RLP encoded bytes */ function payloadLen(RLPItem memory item) internal pure returns (uint256) { return item.len - _payloadOffset(item.memPtr); } /* * @param item RLP encoded list in bytes */ function toList(RLPItem memory item) internal pure returns (RLPItem[] memory) { require(isList(item)); uint256 items = numItems(item); RLPItem[] memory result = new RLPItem[](items); uint256 memPtr = item.memPtr + _payloadOffset(item.memPtr); uint256 dataLen; for (uint256 i = 0; i < items; i++) { dataLen = _itemLength(memPtr); result[i] = RLPItem(dataLen, memPtr); memPtr = memPtr + dataLen; } return result; } // @return indicator whether encoded payload is a list. negate this function call for isData. function isList(RLPItem memory item) internal pure returns (bool) { if (item.len == 0) return false; uint8 byte0; uint256 memPtr = item.memPtr; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < LIST_SHORT_START) return false; return true; } /** RLPItem conversions into data types **/ // @returns raw rlp encoding in bytes function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) { bytes memory result = new bytes(item.len); if (result.length == 0) return result; uint256 ptr; assembly { ptr := add(0x20, result) } copy(item.memPtr, ptr, item.len); return result; } // any non-zero byte is considered true function toBoolean(RLPItem memory item) internal pure returns (bool) { require(item.len == 1); uint256 result; uint256 memPtr = item.memPtr; assembly { result := byte(0, mload(memPtr)) } return result == 0 ? false : true; } function toAddress(RLPItem memory item) internal pure returns (address) { // 1 byte for the length prefix require(item.len == 21); return address(toUint(item)); } function toUint(RLPItem memory item) internal pure returns (uint256) { require(item.len > 0 && item.len <= 33); uint256 offset = _payloadOffset(item.memPtr); uint256 len = item.len - offset; uint256 result; uint256 memPtr = item.memPtr + offset; assembly { result := mload(memPtr) // shfit to the correct location if neccesary if lt(len, 32) { result := div(result, exp(256, sub(32, len))) } } return result; } // enforces 32 byte length function toUintStrict(RLPItem memory item) internal pure returns (uint256) { // one byte prefix require(item.len == 33); uint256 result; uint256 memPtr = item.memPtr + 1; assembly { result := mload(memPtr) } return result; } function toBytes(RLPItem memory item) internal pure returns (bytes memory) { require(item.len > 0); uint256 offset = _payloadOffset(item.memPtr); uint256 len = item.len - offset; // data length bytes memory result = new bytes(len); uint256 destPtr; assembly { destPtr := add(0x20, result) } copy(item.memPtr + offset, destPtr, len); return result; } /* * Private Helpers */ // @return number of payload items inside an encoded list. function numItems(RLPItem memory item) private pure returns (uint256) { if (item.len == 0) return 0; uint256 count = 0; uint256 currPtr = item.memPtr + _payloadOffset(item.memPtr); uint256 endPtr = item.memPtr + item.len; while (currPtr < endPtr) { currPtr = currPtr + _itemLength(currPtr); // skip over an item count++; } return count; } // @return entire rlp item byte length function _itemLength(uint256 memPtr) private pure returns (uint256) { uint256 itemLen; uint256 byte0; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < STRING_SHORT_START) itemLen = 1; else if (byte0 < STRING_LONG_START) itemLen = byte0 - STRING_SHORT_START + 1; else if (byte0 < LIST_SHORT_START) { assembly { let byteLen := sub(byte0, 0xb7) // # of bytes the actual length is memPtr := add(memPtr, 1) // skip over the first byte /* 32 byte word size */ let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len itemLen := add(dataLen, add(byteLen, 1)) } } else if (byte0 < LIST_LONG_START) { itemLen = byte0 - LIST_SHORT_START + 1; } else { assembly { let byteLen := sub(byte0, 0xf7) memPtr := add(memPtr, 1) let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length itemLen := add(dataLen, add(byteLen, 1)) } } return itemLen; } // @return number of bytes until the data function _payloadOffset(uint256 memPtr) private pure returns (uint256) { uint256 byte0; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < STRING_SHORT_START) return 0; else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START)) return 1; else if (byte0 < LIST_SHORT_START) // being explicit return byte0 - (STRING_LONG_START - 1) + 1; else return byte0 - (LIST_LONG_START - 1) + 1; } /* * @param src Pointer to source * @param dest Pointer to destination * @param len Amount of memory to copy from the source */ function copy( uint256 src, uint256 dest, uint256 len ) private pure { if (len == 0) return; // copy as many word sizes as possible for (; len >= WORD_SIZE; len -= WORD_SIZE) { assembly { mstore(dest, mload(src)) } src += WORD_SIZE; dest += WORD_SIZE; } // left over bytes. Mask is used to remove unwanted bytes from the word uint256 mask = 256**(WORD_SIZE - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) // zero out src let destpart := and(mload(dest), mask) // retrieve the bytes mstore(dest, or(destpart, srcpart)) } } } // File: openzeppelin-solidity/contracts/math/SafeMath.sol pragma solidity ^0.5.2; /** * @title SafeMath * @dev Unsigned math operations with safety checks that revert on error */ library SafeMath { /** * @dev Multiplies two unsigned integers, reverts on 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-solidity/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b); return c; } /** * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a); uint256 c = a - b; return c; } /** * @dev Adds two unsigned integers, reverts on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a); return c; } /** * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo), * reverts when dividing by zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0); return a % b; } } // File: contracts/common/mixin/ChainIdMixin.sol pragma solidity ^0.5.2; contract ChainIdMixin { bytes public constant networkId = hex"89"; uint256 public constant CHAINID = 137; } // File: contracts/root/RootChainStorage.sol pragma solidity ^0.5.2; contract RootChainHeader { event NewHeaderBlock( address indexed proposer, uint256 indexed headerBlockId, uint256 indexed reward, uint256 start, uint256 end, bytes32 root ); // housekeeping event event ResetHeaderBlock(address indexed proposer, uint256 indexed headerBlockId); struct HeaderBlock { bytes32 root; uint256 start; uint256 end; uint256 createdAt; address proposer; } } contract RootChainStorage is ProxyStorage, RootChainHeader, ChainIdMixin { bytes32 public heimdallId; uint8 public constant VOTE_TYPE = 2; uint16 internal constant MAX_DEPOSITS = 10000; uint256 public _nextHeaderBlock = MAX_DEPOSITS; uint256 internal _blockDepositId = 1; mapping(uint256 => HeaderBlock) public headerBlocks; Registry internal registry; } // File: contracts/staking/stakeManager/IStakeManager.sol pragma solidity ^0.5.2; contract IStakeManager { // validator replacement function startAuction(uint256 validatorId, uint256 amount) external; function confirmAuctionBid( uint256 validatorId, uint256 heimdallFee, bool acceptDelegation, bytes calldata signerPubkey ) external; function transferFunds( uint256 validatorId, uint256 amount, address delegator ) external returns (bool); function delegationDeposit( uint256 validatorId, uint256 amount, address delegator ) external returns (bool); function stake( uint256 amount, uint256 heimdallFee, bool acceptDelegation, bytes calldata signerPubkey ) external; function unstake(uint256 validatorId) external; function totalStakedFor(address addr) external view returns (uint256); function supportsHistory() external pure returns (bool); function stakeFor( address user, uint256 amount, uint256 heimdallFee, bool acceptDelegation, bytes memory signerPubkey ) public; function checkSignatures( uint256 blockInterval, bytes32 voteHash, bytes32 stateRoot, address proposer, bytes memory sigs ) public returns (uint256); function updateValidatorState(uint256 validatorId, int256 amount) public; function ownerOf(uint256 tokenId) public view returns (address); function slash(bytes memory slashingInfoList) public returns (uint256); function validatorStake(uint256 validatorId) public view returns (uint256); function epoch() public view returns (uint256); function withdrawalDelay() public view returns (uint256); } // File: contracts/root/IRootChain.sol pragma solidity ^0.5.2; interface IRootChain { function slash() external; function submitHeaderBlock(bytes calldata data, bytes calldata sigs) external; function getLastChildBlock() external view returns (uint256); function currentHeaderBlock() external view returns (uint256); } // File: contracts/root/RootChain.sol pragma solidity ^0.5.2; contract RootChain is RootChainStorage, IRootChain { using SafeMath for uint256; using RLPReader for bytes; using RLPReader for RLPReader.RLPItem; modifier onlyDepositManager() { require(msg.sender == registry.getDepositManagerAddress(), "UNAUTHORIZED_DEPOSIT_MANAGER_ONLY"); _; } function submitHeaderBlock(bytes calldata data, bytes calldata sigs) external { (address proposer, uint256 start, uint256 end, bytes32 rootHash, bytes32 accountHash, uint256 _borChainID) = abi .decode(data, (address, uint256, uint256, bytes32, bytes32, uint256)); require(CHAINID == _borChainID, "Invalid bor chain id"); require(_buildHeaderBlock(proposer, start, end, rootHash), "INCORRECT_HEADER_DATA"); // check if it is better to keep it in local storage instead IStakeManager stakeManager = IStakeManager(registry.getStakeManagerAddress()); uint256 _reward = stakeManager.checkSignatures( end.sub(start).add(1), /** prefix 01 to data 01 represents positive vote on data and 00 is negative vote malicious validator can try to send 2/3 on negative vote so 01 is appended */ keccak256(abi.encodePacked(bytes(hex"01"), data)), accountHash, proposer, sigs ); require(_reward != 0, "Invalid checkpoint"); emit NewHeaderBlock(proposer, _nextHeaderBlock, _reward, start, end, rootHash); _nextHeaderBlock = _nextHeaderBlock.add(MAX_DEPOSITS); _blockDepositId = 1; } function updateDepositId(uint256 numDeposits) external onlyDepositManager returns (uint256 depositId) { depositId = currentHeaderBlock().add(_blockDepositId); // deposit ids will be (_blockDepositId, _blockDepositId + 1, .... _blockDepositId + numDeposits - 1) _blockDepositId = _blockDepositId.add(numDeposits); require( // Since _blockDepositId is initialized to 1; only (MAX_DEPOSITS - 1) deposits per header block are allowed _blockDepositId <= MAX_DEPOSITS, "TOO_MANY_DEPOSITS" ); } function getLastChildBlock() external view returns (uint256) { return headerBlocks[currentHeaderBlock()].end; } function slash() external { //TODO: future implementation } function currentHeaderBlock() public view returns (uint256) { return _nextHeaderBlock.sub(MAX_DEPOSITS); } function _buildHeaderBlock( address proposer, uint256 start, uint256 end, bytes32 rootHash ) private returns (bool) { uint256 nextChildBlock; /* The ID of the 1st header block is MAX_DEPOSITS. if _nextHeaderBlock == MAX_DEPOSITS, then the first header block is yet to be submitted, hence nextChildBlock = 0 */ if (_nextHeaderBlock > MAX_DEPOSITS) { nextChildBlock = headerBlocks[currentHeaderBlock()].end + 1; } if (nextChildBlock != start) { return false; } HeaderBlock memory headerBlock = HeaderBlock({ root: rootHash, start: nextChildBlock, end: end, createdAt: now, proposer: proposer }); headerBlocks[_nextHeaderBlock] = headerBlock; return true; } // Housekeeping function. @todo remove later function setNextHeaderBlock(uint256 _value) public onlyOwner { require(_value % MAX_DEPOSITS == 0, "Invalid value"); for (uint256 i = _value; i < _nextHeaderBlock; i += MAX_DEPOSITS) { delete headerBlocks[i]; } _nextHeaderBlock = _value; _blockDepositId = 1; emit ResetHeaderBlock(msg.sender, _nextHeaderBlock); } // Housekeeping function. @todo remove later function setHeimdallId(string memory _heimdallId) public onlyOwner { heimdallId = keccak256(abi.encodePacked(_heimdallId)); } } // File: openzeppelin-solidity/contracts/introspection/IERC165.sol pragma solidity ^0.5.2; /** * @title IERC165 * @dev https://eips.ethereum.org/EIPS/eip-165 */ interface IERC165 { /** * @notice Query if a contract implements an interface * @param interfaceId The interface identifier, as specified in ERC-165 * @dev Interface identification is specified in ERC-165. This function * uses less than 30,000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: openzeppelin-solidity/contracts/token/ERC721/IERC721.sol pragma solidity ^0.5.2; /** * @title ERC721 Non-Fungible Token Standard basic interface * @dev see https://eips.ethereum.org/EIPS/eip-721 */ contract IERC721 is IERC165 { event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); event ApprovalForAll(address indexed owner, address indexed operator, bool approved); function balanceOf(address owner) public view returns (uint256 balance); function ownerOf(uint256 tokenId) public view returns (address owner); function approve(address to, uint256 tokenId) public; function getApproved(uint256 tokenId) public view returns (address operator); function setApprovalForAll(address operator, bool _approved) public; function isApprovedForAll(address owner, address operator) public view returns (bool); function transferFrom( address from, address to, uint256 tokenId ) public; function safeTransferFrom( address from, address to, uint256 tokenId ) public; function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory data ) public; } // File: openzeppelin-solidity/contracts/token/ERC721/IERC721Receiver.sol pragma solidity ^0.5.2; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ contract IERC721Receiver { /** * @notice Handle the receipt of an NFT * @dev The ERC721 smart contract calls this function on the recipient * after a `safeTransfer`. This function MUST return the function selector, * otherwise the caller will revert the transaction. The selector to be * returned can be obtained as `this.onERC721Received.selector`. This * function MAY throw to revert and reject the transfer. * Note: the ERC721 contract address is always the message sender. * @param operator The address which called `safeTransferFrom` function * @param from The address which previously owned the token * @param tokenId The NFT identifier which is being transferred * @param data Additional data with no specified format * @return bytes4 `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` */ function onERC721Received( address operator, address from, uint256 tokenId, bytes memory data ) public returns (bytes4); } // File: openzeppelin-solidity/contracts/utils/Address.sol pragma solidity ^0.5.2; /** * Utility library of inline functions on addresses */ library Address { /** * Returns whether the target address is a contract * @dev This function will return false if invoked during the constructor of a contract, * as the code is not actually created until after the constructor finishes. * @param account address of the account to check * @return whether the target address is a contract */ function isContract(address account) internal view returns (bool) { uint256 size; // XXX Currently there is no better way to check if there is a contract in an address // than to check the size of the code at that address. // See https://ethereum.stackexchange.com/a/14016/36603 // for more details about how this works. // TODO Check this again before the Serenity release, because all addresses will be // contracts then. // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } } // File: openzeppelin-solidity/contracts/drafts/Counters.sol pragma solidity ^0.5.2; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids * * Include with `using Counters for Counters.Counter;` * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the SafeMath * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never * directly accessed. */ library Counters { using SafeMath for uint256; struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { counter._value += 1; } function decrement(Counter storage counter) internal { counter._value = counter._value.sub(1); } } // File: openzeppelin-solidity/contracts/introspection/ERC165.sol pragma solidity ^0.5.2; /** * @title ERC165 * @author Matt Condon (@shrugs) * @dev Implements ERC165 using a lookup table. */ contract ERC165 is IERC165 { bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; /* * 0x01ffc9a7 === * bytes4(keccak256('supportsInterface(bytes4)')) */ /** * @dev a mapping of interface id to whether or not it's supported */ mapping(bytes4 => bool) private _supportedInterfaces; /** * @dev A contract implementing SupportsInterfaceWithLookup * implement ERC165 itself */ constructor() internal { _registerInterface(_INTERFACE_ID_ERC165); } /** * @dev implement supportsInterface(bytes4) using a lookup table */ function supportsInterface(bytes4 interfaceId) external view returns (bool) { return _supportedInterfaces[interfaceId]; } /** * @dev internal method for registering an interface */ function _registerInterface(bytes4 interfaceId) internal { require(interfaceId != 0xffffffff); _supportedInterfaces[interfaceId] = true; } } // File: openzeppelin-solidity/contracts/token/ERC721/ERC721.sol pragma solidity ^0.5.2; /** * @title ERC721 Non-Fungible Token Standard basic implementation * @dev see https://eips.ethereum.org/EIPS/eip-721 */ contract ERC721 is ERC165, IERC721 { using SafeMath for uint256; using Address for address; using Counters for Counters.Counter; // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector` bytes4 private constant _ERC721_RECEIVED = 0x150b7a02; // Mapping from token ID to owner mapping(uint256 => address) private _tokenOwner; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to number of owned token mapping(address => Counters.Counter) private _ownedTokensCount; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd; /* * 0x80ac58cd === * bytes4(keccak256('balanceOf(address)')) ^ * bytes4(keccak256('ownerOf(uint256)')) ^ * bytes4(keccak256('approve(address,uint256)')) ^ * bytes4(keccak256('getApproved(uint256)')) ^ * bytes4(keccak256('setApprovalForAll(address,bool)')) ^ * bytes4(keccak256('isApprovedForAll(address,address)')) ^ * bytes4(keccak256('transferFrom(address,address,uint256)')) ^ * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^ * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) */ constructor() public { // register the supported interfaces to conform to ERC721 via ERC165 _registerInterface(_INTERFACE_ID_ERC721); } /** * @dev Gets the balance of the specified address * @param owner address to query the balance of * @return uint256 representing the amount owned by the passed address */ function balanceOf(address owner) public view returns (uint256) { require(owner != address(0)); return _ownedTokensCount[owner].current(); } /** * @dev Gets the owner of the specified token ID * @param tokenId uint256 ID of the token to query the owner of * @return address currently marked as the owner of the given token ID */ function ownerOf(uint256 tokenId) public view returns (address) { address owner = _tokenOwner[tokenId]; require(owner != address(0)); return owner; } /** * @dev Approves another address to transfer the given token ID * The zero address indicates there is no approved address. * There can only be one approved address per token at a given time. * Can only be called by the token owner or an approved operator. * @param to address to be approved for the given token ID * @param tokenId uint256 ID of the token to be approved */ function approve(address to, uint256 tokenId) public { address owner = ownerOf(tokenId); require(to != owner); require(msg.sender == owner || isApprovedForAll(owner, msg.sender)); _tokenApprovals[tokenId] = to; emit Approval(owner, to, tokenId); } /** * @dev Gets the approved address for a token ID, or zero if no address set * Reverts if the token ID does not exist. * @param tokenId uint256 ID of the token to query the approval of * @return address currently approved for the given token ID */ function getApproved(uint256 tokenId) public view returns (address) { require(_exists(tokenId)); return _tokenApprovals[tokenId]; } /** * @dev Sets or unsets the approval of a given operator * An operator is allowed to transfer all tokens of the sender on their behalf * @param to operator address to set the approval * @param approved representing the status of the approval to be set */ function setApprovalForAll(address to, bool approved) public { require(to != msg.sender); _operatorApprovals[msg.sender][to] = approved; emit ApprovalForAll(msg.sender, to, approved); } /** * @dev Tells whether an operator is approved by a given owner * @param owner owner address which you want to query the approval of * @param operator operator address which you want to query the approval of * @return bool whether the given operator is approved by the given owner */ function isApprovedForAll(address owner, address operator) public view returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev Transfers the ownership of a given token ID to another address * Usage of this method is discouraged, use `safeTransferFrom` whenever possible * Requires the msg.sender to be the owner, approved, or operator * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred */ function transferFrom( address from, address to, uint256 tokenId ) public { require(_isApprovedOrOwner(msg.sender, tokenId)); _transferFrom(from, to, tokenId); } /** * @dev Safely transfers the ownership of a given token ID to another address * If the target address is a contract, it must implement `onERC721Received`, * which is called upon a safe transfer, and return the magic value * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, * the transfer is reverted. * Requires the msg.sender to be the owner, approved, or operator * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred */ function safeTransferFrom( address from, address to, uint256 tokenId ) public { safeTransferFrom(from, to, tokenId, ""); } /** * @dev Safely transfers the ownership of a given token ID to another address * If the target address is a contract, it must implement `onERC721Received`, * which is called upon a safe transfer, and return the magic value * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, * the transfer is reverted. * Requires the msg.sender to be the owner, approved, or operator * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred * @param _data bytes data to send along with a safe transfer check */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public { transferFrom(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, _data)); } /** * @dev Returns whether the specified token exists * @param tokenId uint256 ID of the token to query the existence of * @return bool whether the token exists */ function _exists(uint256 tokenId) internal view returns (bool) { address owner = _tokenOwner[tokenId]; return owner != address(0); } /** * @dev Returns whether the given spender can transfer a given token ID * @param spender address of the spender to query * @param tokenId uint256 ID of the token to be transferred * @return bool whether the msg.sender is approved for the given token ID, * is an operator of the owner, or is the owner of the token */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) { address owner = ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } /** * @dev Internal function to mint a new token * Reverts if the given token ID already exists * @param to The address that will own the minted token * @param tokenId uint256 ID of the token to be minted */ function _mint(address to, uint256 tokenId) internal { require(to != address(0)); require(!_exists(tokenId)); _tokenOwner[tokenId] = to; _ownedTokensCount[to].increment(); emit Transfer(address(0), to, tokenId); } /** * @dev Internal function to burn a specific token * Reverts if the token does not exist * Deprecated, use _burn(uint256) instead. * @param owner owner of the token to burn * @param tokenId uint256 ID of the token being burned */ function _burn(address owner, uint256 tokenId) internal { require(ownerOf(tokenId) == owner); _clearApproval(tokenId); _ownedTokensCount[owner].decrement(); _tokenOwner[tokenId] = address(0); emit Transfer(owner, address(0), tokenId); } /** * @dev Internal function to burn a specific token * Reverts if the token does not exist * @param tokenId uint256 ID of the token being burned */ function _burn(uint256 tokenId) internal { _burn(ownerOf(tokenId), tokenId); } /** * @dev Internal function to transfer ownership of a given token ID to another address. * As opposed to transferFrom, this imposes no restrictions on msg.sender. * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred */ function _transferFrom( address from, address to, uint256 tokenId ) internal { require(ownerOf(tokenId) == from); require(to != address(0)); _clearApproval(tokenId); _ownedTokensCount[from].decrement(); _ownedTokensCount[to].increment(); _tokenOwner[tokenId] = to; emit Transfer(from, to, tokenId); } /** * @dev Internal function to invoke `onERC721Received` on a target address * The call is not executed if the target address is not a contract * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) internal returns (bool) { if (!to.isContract()) { return true; } bytes4 retval = IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, _data); return (retval == _ERC721_RECEIVED); } /** * @dev Private function to clear current approval of a given token ID * @param tokenId uint256 ID of the token to be transferred */ function _clearApproval(uint256 tokenId) private { if (_tokenApprovals[tokenId] != address(0)) { _tokenApprovals[tokenId] = address(0); } } } // File: contracts/root/withdrawManager/ExitNFT.sol pragma solidity ^0.5.2; contract ExitNFT is ERC721 { Registry internal registry; modifier onlyWithdrawManager() { require(msg.sender == registry.getWithdrawManagerAddress(), "UNAUTHORIZED_WITHDRAW_MANAGER_ONLY"); _; } constructor(address _registry) public { registry = Registry(_registry); } function mint(address _owner, uint256 _tokenId) external onlyWithdrawManager { _mint(_owner, _tokenId); } function burn(uint256 _tokenId) external onlyWithdrawManager { _burn(_tokenId); } function exists(uint256 tokenId) public view returns (bool) { return _exists(tokenId); } } // File: contracts/root/withdrawManager/WithdrawManagerStorage.sol pragma solidity ^0.5.2; contract ExitsDataStructure { struct Input { address utxoOwner; address predicate; address token; } struct PlasmaExit { uint256 receiptAmountOrNFTId; bytes32 txHash; address owner; address token; bool isRegularExit; address predicate; // Mapping from age of input to Input mapping(uint256 => Input) inputs; } } contract WithdrawManagerHeader is ExitsDataStructure { event Withdraw(uint256 indexed exitId, address indexed user, address indexed token, uint256 amount); event ExitStarted( address indexed exitor, uint256 indexed exitId, address indexed token, uint256 amount, bool isRegularExit ); event ExitUpdated(uint256 indexed exitId, uint256 indexed age, address signer); event ExitPeriodUpdate(uint256 indexed oldExitPeriod, uint256 indexed newExitPeriod); event ExitCancelled(uint256 indexed exitId); } contract WithdrawManagerStorage is ProxyStorage, WithdrawManagerHeader { // 0.5 week = 7 * 86400 / 2 = 302400 uint256 public HALF_EXIT_PERIOD = 302400; // Bonded exits collaterized at 0.1 ETH uint256 internal constant BOND_AMOUNT = 10**17; Registry internal registry; RootChain internal rootChain; mapping(uint128 => bool) isKnownExit; mapping(uint256 => PlasmaExit) public exits; // mapping with token => (owner => exitId) keccak(token+owner) keccak(token+owner+tokenId) mapping(bytes32 => uint256) public ownerExits; mapping(address => address) public exitsQueues; ExitNFT public exitNft; // ERC721, ERC20 and Weth transfers require 155000, 100000, 52000 gas respectively // Processing each exit in a while loop iteration requires ~52000 gas (@todo check if this changed) // uint32 constant internal ITERATION_GAS = 52000; // So putting an upper limit of 155000 + 52000 + leeway uint32 public ON_FINALIZE_GAS_LIMIT = 300000; uint256 public exitWindow; } // File: contracts/root/withdrawManager/WithdrawManagerProxy.sol pragma solidity ^0.5.2; contract WithdrawManagerProxy is Proxy, WithdrawManagerStorage { constructor( address _proxyTo, address _registry, address _rootChain, address _exitNft ) public Proxy(_proxyTo) { registry = Registry(_registry); rootChain = RootChain(_rootChain); exitNft = ExitNFT(_exitNft); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":false,"inputs":[{"internalType":"address","name":"_newProxyTo","type":"address"}],"name":"updateImplementation","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"exitWindow","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"exits","outputs":[{"internalType":"uint256","name":"receiptAmountOrNFTId","type":"uint256"},{"internalType":"bytes32","name":"txHash","type":"bytes32"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"bool","name":"isRegularExit","type":"bool"},{"internalType":"address","name":"predicate","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"proxyType","outputs":[{"internalType":"uint256","name":"proxyTypeId","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"ownerExits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ON_FINALIZE_GAS_LIMIT","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"exitsQueues","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"HALF_EXIT_PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"exitNft","outputs":[{"internalType":"contract ExitNFT","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_proxyTo","type":"address"},{"internalType":"address","name":"_registry","type":"address"},{"internalType":"address","name":"_rootChain","type":"address"},{"internalType":"address","name":"_exitNft","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"exitId","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"exitor","type":"address"},{"indexed":true,"internalType":"uint256","name":"exitId","type":"uint256"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isRegularExit","type":"bool"}],"name":"ExitStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"exitId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"age","type":"uint256"},{"indexed":false,"internalType":"address","name":"signer","type":"address"}],"name":"ExitUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"oldExitPeriod","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"newExitPeriod","type":"uint256"}],"name":"ExitPeriodUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"exitId","type":"uint256"}],"name":"ExitCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_new","type":"address"},{"indexed":true,"internalType":"address","name":"_old","type":"address"}],"name":"ProxyUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_prevOwner","type":"address"},{"indexed":false,"internalType":"address","name":"_newOwner","type":"address"}],"name":"OwnerUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]
Contract Creation Code
608060405262049d406002556009805463ffffffff60a01b1916760493e0000000000000000000000000000000000000000017905534801561004057600080fd5b506040516109ac3803806109ac8339818101604052608081101561006357600080fd5b5080516020820151604080840151606090940151600080546001600160a01b0319163317808255925194959394919286926001600160a01b039190911691907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a36100d9816001600160e01b0361011d16565b50600380546001600160a01b039485166001600160a01b031991821617909155600480549385169382169390931790925560098054919093169116179055506102a4565b61012e6001600160e01b0361027016565b61013757600080fd5b6001600160a01b0381166101ac57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f494e56414c49445f50524f58595f414444524553530000000000000000000000604482015290519081900360640190fd5b6101be816001600160e01b0361028116565b610213576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806109876025913960400191505060405180910390fd5b6001546040516001600160a01b03918216918316907fd32d24edea94f55e932d9a008afc425a8561462d1b1f57bc6e508e9a6b9509e190600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b0316331490565b60006001600160a01b0382166102995750600061029f565b50803b15155b919050565b6106d4806102b36000396000f3fe6080604052600436106100dd5760003560e01c80638da5cb5b1161007f578063d11f045c11610059578063d11f045c146102dc578063ed4a0be81461030f578063edeca09b14610324578063f2fde38b14610339576100dd565b80638da5cb5b146102705780638f32d59b1461028557806396cbd812146102ae576100dd565b80634555d5c9116100bb5780634555d5c9146101eb5780635c60da1b14610200578063661429c814610231578063715018a61461025b576100dd565b8063025b22bc146101295780631e29848b1461015c578063342de17914610183575b60015460408051602036601f8101829004820283018201909352828252610127936001600160a01b0316926000918190840183828082843760009201919091525061036c92505050565b005b34801561013557600080fd5b506101276004803603602081101561014c57600080fd5b50356001600160a01b0316610394565b34801561016857600080fd5b50610171610499565b60408051918252519081900360200190f35b34801561018f57600080fd5b506101ad600480360360208110156101a657600080fd5b503561049f565b6040805196875260208701959095526001600160a01b03938416868601529183166060860152151560808501521660a0830152519081900360c00190f35b3480156101f757600080fd5b506101716104e8565b34801561020c57600080fd5b506102156104ed565b604080516001600160a01b039092168252519081900360200190f35b34801561023d57600080fd5b506101716004803603602081101561025457600080fd5b50356104fc565b34801561026757600080fd5b5061012761050e565b34801561027c57600080fd5b50610215610569565b34801561029157600080fd5b5061029a610578565b604080519115158252519081900360200190f35b3480156102ba57600080fd5b506102c3610589565b6040805163ffffffff9092168252519081900360200190f35b3480156102e857600080fd5b50610215600480360360208110156102ff57600080fd5b50356001600160a01b031661059c565b34801561031b57600080fd5b506101716105b7565b34801561033057600080fd5b506102156105bd565b34801561034557600080fd5b506101276004803603602081101561035c57600080fd5b50356001600160a01b03166105cc565b600080825160208401856127105a03f43d604051816000823e828015610390578282f35b8282fd5b61039c610578565b6103a557600080fd5b6001600160a01b0381166103f8576040805162461bcd60e51b8152602060048201526015602482015274494e56414c49445f50524f58595f4144445245535360581b604482015290519081900360640190fd5b610401816105e9565b61043c5760405162461bcd60e51b815260040180806020018281038252602581526020018061067b6025913960400191505060405180910390fd5b6001546040516001600160a01b03918216918316907fd32d24edea94f55e932d9a008afc425a8561462d1b1f57bc6e508e9a6b9509e190600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b600a5481565b60066020526000908152604090208054600182015460028301546003840154600490940154929391926001600160a01b039182169282811692600160a01b90910460ff16911686565b600290565b6001546001600160a01b031690565b60076020526000908152604090205481565b610516610578565b61051f57600080fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b600954600160a01b900463ffffffff1681565b6008602052600090815260409020546001600160a01b031681565b60025481565b6009546001600160a01b031681565b6105d4610578565b6105dd57600080fd5b6105e68161060c565b50565b60006001600160a01b03821661060157506000610607565b50803b15155b919050565b6001600160a01b03811661061f57600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b039290921691909117905556fe44455354494e4154494f4e5f414444524553535f49535f4e4f545f415f434f4e5452414354a265627a7a723158205a272c047ceef09d433772098613b6e2996b4e3ade0edd1d5155185d42eb487c64736f6c634300050b003244455354494e4154494f4e5f414444524553535f49535f4e4f545f415f434f4e5452414354000000000000000000000000c354bea902429a3c47467967e55fd337ca2e1ad000000000000000000000000033a02e6cc863d393d6bf231b697b82f6e499ca7100000000000000000000000086e4dc95c7fbdbf52e33d563bbdb00823894c287000000000000000000000000df74156420bd57ab387b195ed81eca36f9fabaca
Deployed Bytecode
0x6080604052600436106100dd5760003560e01c80638da5cb5b1161007f578063d11f045c11610059578063d11f045c146102dc578063ed4a0be81461030f578063edeca09b14610324578063f2fde38b14610339576100dd565b80638da5cb5b146102705780638f32d59b1461028557806396cbd812146102ae576100dd565b80634555d5c9116100bb5780634555d5c9146101eb5780635c60da1b14610200578063661429c814610231578063715018a61461025b576100dd565b8063025b22bc146101295780631e29848b1461015c578063342de17914610183575b60015460408051602036601f8101829004820283018201909352828252610127936001600160a01b0316926000918190840183828082843760009201919091525061036c92505050565b005b34801561013557600080fd5b506101276004803603602081101561014c57600080fd5b50356001600160a01b0316610394565b34801561016857600080fd5b50610171610499565b60408051918252519081900360200190f35b34801561018f57600080fd5b506101ad600480360360208110156101a657600080fd5b503561049f565b6040805196875260208701959095526001600160a01b03938416868601529183166060860152151560808501521660a0830152519081900360c00190f35b3480156101f757600080fd5b506101716104e8565b34801561020c57600080fd5b506102156104ed565b604080516001600160a01b039092168252519081900360200190f35b34801561023d57600080fd5b506101716004803603602081101561025457600080fd5b50356104fc565b34801561026757600080fd5b5061012761050e565b34801561027c57600080fd5b50610215610569565b34801561029157600080fd5b5061029a610578565b604080519115158252519081900360200190f35b3480156102ba57600080fd5b506102c3610589565b6040805163ffffffff9092168252519081900360200190f35b3480156102e857600080fd5b50610215600480360360208110156102ff57600080fd5b50356001600160a01b031661059c565b34801561031b57600080fd5b506101716105b7565b34801561033057600080fd5b506102156105bd565b34801561034557600080fd5b506101276004803603602081101561035c57600080fd5b50356001600160a01b03166105cc565b600080825160208401856127105a03f43d604051816000823e828015610390578282f35b8282fd5b61039c610578565b6103a557600080fd5b6001600160a01b0381166103f8576040805162461bcd60e51b8152602060048201526015602482015274494e56414c49445f50524f58595f4144445245535360581b604482015290519081900360640190fd5b610401816105e9565b61043c5760405162461bcd60e51b815260040180806020018281038252602581526020018061067b6025913960400191505060405180910390fd5b6001546040516001600160a01b03918216918316907fd32d24edea94f55e932d9a008afc425a8561462d1b1f57bc6e508e9a6b9509e190600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b600a5481565b60066020526000908152604090208054600182015460028301546003840154600490940154929391926001600160a01b039182169282811692600160a01b90910460ff16911686565b600290565b6001546001600160a01b031690565b60076020526000908152604090205481565b610516610578565b61051f57600080fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b600954600160a01b900463ffffffff1681565b6008602052600090815260409020546001600160a01b031681565b60025481565b6009546001600160a01b031681565b6105d4610578565b6105dd57600080fd5b6105e68161060c565b50565b60006001600160a01b03821661060157506000610607565b50803b15155b919050565b6001600160a01b03811661061f57600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b039290921691909117905556fe44455354494e4154494f4e5f414444524553535f49535f4e4f545f415f434f4e5452414354a265627a7a723158205a272c047ceef09d433772098613b6e2996b4e3ade0edd1d5155185d42eb487c64736f6c634300050b0032
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000c354bea902429a3c47467967e55fd337ca2e1ad000000000000000000000000033a02e6cc863d393d6bf231b697b82f6e499ca7100000000000000000000000086e4dc95c7fbdbf52e33d563bbdb00823894c287000000000000000000000000df74156420bd57ab387b195ed81eca36f9fabaca
-----Decoded View---------------
Arg [0] : _proxyTo (address): 0xC354BEa902429A3c47467967E55fd337CA2e1Ad0
Arg [1] : _registry (address): 0x33a02E6cC863D393d6Bf231B697b82F6e499cA71
Arg [2] : _rootChain (address): 0x86E4Dc95c7FBdBf52e33D563BbDB00823894C287
Arg [3] : _exitNft (address): 0xDF74156420Bd57ab387B195ed81EcA36F9fABAca
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000c354bea902429a3c47467967e55fd337ca2e1ad0
Arg [1] : 00000000000000000000000033a02e6cc863d393d6bf231b697b82f6e499ca71
Arg [2] : 00000000000000000000000086e4dc95c7fbdbf52e33d563bbdb00823894c287
Arg [3] : 000000000000000000000000df74156420bd57ab387b195ed81eca36f9fabaca
Deployed Bytecode Sourcemap
53211:357:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11528:7;;11515:31;;;;11537:8;11515:31;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;11528:7:0;;-1:-1:-1;;11537:8:0;;11515:31;;-1:-1:-1;11537:8:0;;-1:-1:-1;11515:31:0;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;11515:12:0;;-1:-1:-1;;;11515:31:0:i;:::-;53211:357;11661:314;;8:9:-1;5:2;;;30:1;27;20:12;5:2;11661:314:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;11661:314:0;-1:-1:-1;;;;;11661:314:0;;:::i;53081:25::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;53081:25:0;;;:::i;:::-;;;;;;;;;;;;;;;;52434:43;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52434:43:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;52434:43:0;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;;;;;52434:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9975:129;;8:9:-1;5:2;;;30:1;27;20:12;5:2;9975:129:0;;;:::i;11562:91::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;11562:91:0;;;:::i;:::-;;;;-1:-1:-1;;;;;11562:91:0;;;;;;;;;;;;;;52580:45;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52580:45:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;52580:45:0;;:::i;8562:140::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;8562:140:0;;;:::i;7772:79::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;7772:79:0;;;:::i;8107:92::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;8107:92:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;53028:44;;8:9:-1;5:2;;;30:1;27;20:12;5:2;53028:44:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;52632:46;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52632:46:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;52632:46:0;-1:-1:-1;;;;;52632:46:0;;:::i;52172:40::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52172:40:0;;;:::i;52685:22::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52685:22:0;;;:::i;8879:109::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;8879:109:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;8879:109:0;-1:-1:-1;;;;;8879:109:0;;:::i;10178:775::-;10440:1;10437;10425:9;10419:16;10412:4;10401:9;10397:20;10391:4;10383:5;10378:3;10374:15;10361:81;10468:14;10515:4;10509:11;10557:4;10554:1;10549:3;10534:28;10760:6;10784:66;;;;10911:4;10906:3;10899:17;10784:66;10826:4;10821:3;10814:17;11661:314;7984:9;:7;:9::i;:::-;7976:18;;;;;;-1:-1:-1;;;;;11748:27:0;;11740:61;;;;;-1:-1:-1;;;11740:61:0;;;;;;;;;;;;-1:-1:-1;;;11740:61:0;;;;;;;;;;;;;;;11820:23;11831:11;11820:10;:23::i;:::-;11812:73;;;;-1:-1:-1;;;11812:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11927:7;;11901:34;;-1:-1:-1;;;;;11927:7:0;;;;11901:34;;;;;11927:7;;11901:34;11946:7;:21;;-1:-1:-1;;;;;;11946:21:0;-1:-1:-1;;;;;11946:21:0;;;;;;;;;;11661:314::o;53081:25::-;;;;:::o;52434:43::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;52434:43:0;;;;;;;;-1:-1:-1;;;52434:43:0;;;;;;;;:::o;9975:129::-;10095:1;;9975:129::o;11562:91::-;11638:7;;-1:-1:-1;;;;;11638:7:0;11562:91;:::o;52580:45::-;;;;;;;;;;;;;:::o;8562:140::-;7984:9;:7;:9::i;:::-;7976:18;;;;;;8661:1;8645:6;;8624:40;;-1:-1:-1;;;;;8645:6:0;;;;8624:40;;8661:1;;8624:40;8692:1;8675:19;;-1:-1:-1;;;;;;8675:19:0;;;8562:140::o;7772:79::-;7810:7;7837:6;-1:-1:-1;;;;;7837:6:0;7772:79;:::o;8107:92::-;8147:4;8185:6;-1:-1:-1;;;;;8185:6:0;8171:10;:20;;8107:92::o;53028:44::-;;;-1:-1:-1;;;53028:44:0;;;;;:::o;52632:46::-;;;;;;;;;;;;-1:-1:-1;;;;;52632:46:0;;:::o;52172:40::-;;;;:::o;52685:22::-;;;-1:-1:-1;;;;;52685:22:0;;:::o;8879:109::-;7984:9;:7;:9::i;:::-;7976:18;;;;;;8952:28;8971:8;8952:18;:28::i;:::-;8879:109;:::o;11983:274::-;12043:4;-1:-1:-1;;;;;12064:21:0;;12060:66;;-1:-1:-1;12109:5:0;12102:12;;12060:66;-1:-1:-1;12193:20:0;;12241:8;;11983:274;;;;:::o;9138:187::-;-1:-1:-1;;;;;9212:22:0;;9204:31;;;;;;9272:6;;;9251:38;;-1:-1:-1;;;;;9251:38:0;;;;9272:6;;;9251:38;;;9300:6;:17;;-1:-1:-1;;;;;;9300:17:0;-1:-1:-1;;;;;9300:17:0;;;;;;;;;;9138:187::o
Swarm Source
bzzr://5a272c047ceef09d433772098613b6e2996b4e3ade0edd1d5155185d42eb487c
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.