Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Deposit ERC20 | 16493601 | 688 days ago | IN | 0 ETH | 0.00101693 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
DepositManager
Compiler Version
v0.5.11+commit.c082d0b4
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2020-06-04 */ /** Matic network contracts */ pragma solidity ^0.5.2; 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); } interface IERC20 { function transfer(address to, uint256 value) external returns (bool); function approve(address spender, uint256 value) external returns (bool); function transferFrom(address from, address to, uint256 value) external returns (bool); function totalSupply() external view returns (uint256); function balanceOf(address who) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); } /** * @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); } 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; } 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; } } contract ContractReceiver { /// @dev Function that is called when a user or another contract wants to transfer funds. /// @param _from Transaction initiator, analogue of msg.sender /// @param _value Number of tokens to transfer. /// @param _data Data containig a function signature and/or parameters function tokenFallback(address _from, uint256 _value, bytes memory _data) public; } interface IGovernance { function update(address target, bytes calldata data) external; } contract Governable { IGovernance public governance; constructor(address _governance) public { governance = IGovernance(_governance); } modifier onlyGovernance() { require( msg.sender == address(governance), "Only governance contract is authorized" ); _; } } 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; } 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]; } } /** * @title ERC20 interface * @dev see https://eips.ethereum.org/EIPS/eip-20 */ /** * @title SafeMath * @dev Unsigned math operations with safety checks that revert on error */ /** * @title Standard ERC20 token * * @dev Implementation of the basic standard token. * https://eips.ethereum.org/EIPS/eip-20 * Originally based on code by FirstBlood: * https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol * * This implementation emits additional Approval events, allowing applications to reconstruct the allowance status for * all accounts just by listening to said events. Note that this isn't required by the specification, and other * compliant implementations may not do it. */ contract ERC20 is IERC20 { using SafeMath for uint256; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowed; uint256 private _totalSupply; /** * @dev Total number of tokens in existence */ function totalSupply() public view returns (uint256) { return _totalSupply; } /** * @dev Gets the balance of the specified address. * @param owner The address to query the balance of. * @return A uint256 representing the amount owned by the passed address. */ function balanceOf(address owner) public view returns (uint256) { return _balances[owner]; } /** * @dev Function to check the amount of tokens that an owner allowed to a spender. * @param owner address The address which owns the funds. * @param spender address The address which will spend the funds. * @return A uint256 specifying the amount of tokens still available for the spender. */ function allowance(address owner, address spender) public view returns (uint256) { return _allowed[owner][spender]; } /** * @dev Transfer token to a specified address * @param to The address to transfer to. * @param value The amount to be transferred. */ function transfer(address to, uint256 value) public returns (bool) { _transfer(msg.sender, to, value); return true; } /** * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. * 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 * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. */ function approve(address spender, uint256 value) public returns (bool) { _approve(msg.sender, spender, value); return true; } /** * @dev Transfer tokens from one address to another. * Note that while this function emits an Approval event, this is not required as per the specification, * and other compliant implementations may not emit the event. * @param from address The address which you want to send tokens from * @param to address The address which you want to transfer to * @param value uint256 the amount of tokens to be transferred */ function transferFrom(address from, address to, uint256 value) public returns (bool) { _transfer(from, to, value); _approve(from, msg.sender, _allowed[from][msg.sender].sub(value)); return true; } /** * @dev Increase the amount of tokens that an owner allowed to a spender. * approve should be called when _allowed[msg.sender][spender] == 0. To increment * allowed value is better to use this function to avoid 2 calls (and wait until * the first transaction is mined) * From MonolithDAO Token.sol * Emits an Approval event. * @param spender The address which will spend the funds. * @param addedValue The amount of tokens to increase the allowance by. */ function increaseAllowance(address spender, uint256 addedValue) public returns (bool) { _approve(msg.sender, spender, _allowed[msg.sender][spender].add(addedValue)); return true; } /** * @dev Decrease the amount of tokens that an owner allowed to a spender. * approve should be called when _allowed[msg.sender][spender] == 0. To decrement * allowed value is better to use this function to avoid 2 calls (and wait until * the first transaction is mined) * From MonolithDAO Token.sol * Emits an Approval event. * @param spender The address which will spend the funds. * @param subtractedValue The amount of tokens to decrease the allowance by. */ function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) { _approve(msg.sender, spender, _allowed[msg.sender][spender].sub(subtractedValue)); return true; } /** * @dev Transfer token for a specified addresses * @param from The address to transfer from. * @param to The address to transfer to. * @param value The amount to be transferred. */ function _transfer(address from, address to, uint256 value) internal { require(to != address(0)); _balances[from] = _balances[from].sub(value); _balances[to] = _balances[to].add(value); emit Transfer(from, to, value); } /** * @dev Internal function that mints an amount of the token and assigns it to * an account. This encapsulates the modification of balances such that the * proper events are emitted. * @param account The account that will receive the created tokens. * @param value The amount that will be created. */ function _mint(address account, uint256 value) internal { require(account != address(0)); _totalSupply = _totalSupply.add(value); _balances[account] = _balances[account].add(value); emit Transfer(address(0), account, value); } /** * @dev Internal function that burns an amount of the token of a given * account. * @param account The account whose tokens will be burnt. * @param value The amount that will be burnt. */ function _burn(address account, uint256 value) internal { require(account != address(0)); _totalSupply = _totalSupply.sub(value); _balances[account] = _balances[account].sub(value); emit Transfer(account, address(0), value); } /** * @dev Approve an address to spend another addresses' tokens. * @param owner The address that owns the tokens. * @param spender The address that will spend the tokens. * @param value The number of tokens that can be spent. */ function _approve(address owner, address spender, uint256 value) internal { require(spender != address(0)); require(owner != address(0)); _allowed[owner][spender] = value; emit Approval(owner, spender, value); } /** * @dev Internal function that burns an amount of the token of a given * account, deducting from the sender's allowance for said account. Uses the * internal burn function. * Emits an Approval event (reflecting the reduced allowance). * @param account The account whose tokens will be burnt. * @param value The amount that will be burnt. */ function _burnFrom(address account, uint256 value) internal { _burn(account, value); _approve(account, msg.sender, _allowed[account][msg.sender].sub(value)); } } contract WETH is ERC20 { event Deposit(address indexed dst, uint256 wad); event Withdrawal(address indexed src, uint256 wad); function deposit() public payable; function withdraw(uint256 wad) public; function withdraw(uint256 wad, address user) public; } interface IDepositManager { function depositEther() external payable; function transferAssets( address _token, address _user, uint256 _amountOrNFTId ) external; function depositERC20(address _token, uint256 _amount) external; function depositERC721(address _token, uint256 _tokenId) external; } 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 { uint len; uint memPtr; } struct Iterator { RLPItem item; // Item that's being iterated over. uint 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)); uint ptr = self.nextPtr; uint 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) { uint 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)); uint ptr = self.memPtr + _payloadOffset(self.memPtr); return Iterator(self, ptr); } /* * @param item RLP encoded bytes */ function rlpLen(RLPItem memory item) internal pure returns (uint) { return item.len; } /* * @param item RLP encoded bytes */ function payloadLen(RLPItem memory item) internal pure returns (uint) { 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)); uint items = numItems(item); RLPItem[] memory result = new RLPItem[](items); uint memPtr = item.memPtr + _payloadOffset(item.memPtr); uint dataLen; for (uint 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; uint 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; uint 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); uint result; uint 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 (uint) { require(item.len > 0 && item.len <= 33); uint offset = _payloadOffset(item.memPtr); uint len = item.len - offset; uint result; uint 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 (uint) { // one byte prefix require(item.len == 33); uint result; uint memPtr = item.memPtr + 1; assembly { result := mload(memPtr) } return result; } function toBytes(RLPItem memory item) internal pure returns (bytes memory) { require(item.len > 0); uint offset = _payloadOffset(item.memPtr); uint len = item.len - offset; // data length bytes memory result = new bytes(len); uint 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 (uint) { if (item.len == 0) return 0; uint count = 0; uint currPtr = item.memPtr + _payloadOffset(item.memPtr); uint 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(uint memPtr) private pure returns (uint) { uint itemLen; uint 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(uint memPtr) private pure returns (uint) { uint 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(uint src, uint dest, uint 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 uint 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)) } } } 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; } } contract ProxyStorage is Ownable { address internal proxyTo; } contract ChainIdMixin { bytes constant public networkId = hex"3A99"; uint256 constant public CHAINID = 15001; } 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; } 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); } 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); } 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)); } } contract StateSender is Ownable { using SafeMath for uint256; uint256 public counter; mapping(address => address) public registrations; event NewRegistration( address indexed user, address indexed sender, address indexed receiver ); event RegistrationUpdated( address indexed user, address indexed sender, address indexed receiver ); event StateSynced( uint256 indexed id, address indexed contractAddress, bytes data ); modifier onlyRegistered(address receiver) { require(registrations[receiver] == msg.sender, "Invalid sender"); _; } function syncState(address receiver, bytes calldata data) external onlyRegistered(receiver) { counter = counter.add(1); emit StateSynced(counter, receiver, data); } // register new contract for state sync function register(address sender, address receiver) public { require( isOwner() || registrations[receiver] == msg.sender, "StateSender.register: Not authorized to register" ); registrations[receiver] = sender; if (registrations[receiver] == address(0)) { emit NewRegistration(msg.sender, sender, receiver); } else { emit RegistrationUpdated(msg.sender, sender, receiver); } } } contract Lockable is Governable { bool public locked; modifier onlyWhenUnlocked() { require(!locked, "Is Locked"); _; } constructor(address _governance) public Governable(_governance) {} function lock() external onlyGovernance { locked = true; } function unlock() external onlyGovernance { locked = false; } } contract DepositManagerHeader { event NewDepositBlock(address indexed owner, address indexed token, uint256 amountOrNFTId, uint256 depositBlockId); event MaxErc20DepositUpdate(uint256 indexed oldLimit, uint256 indexed newLimit); struct DepositBlock { bytes32 depositHash; uint256 createdAt; } } contract DepositManagerStorage is ProxyStorage, Lockable, DepositManagerHeader { Registry public registry; RootChain public rootChain; StateSender public stateSender; mapping(uint256 => DepositBlock) public deposits; address public childChain; uint256 public maxErc20Deposit = 100 * (10**18); } contract DepositManager is DepositManagerStorage, IDepositManager, IERC721Receiver, ContractReceiver { using SafeMath for uint256; modifier isTokenMapped(address _token) { require(registry.isTokenMapped(_token), "TOKEN_NOT_SUPPORTED"); _; } modifier isPredicateAuthorized() { require(uint8(registry.predicates(msg.sender)) != 0, "Not a valid predicate"); _; } constructor() public Lockable(address(0x0)) {} // deposit ETH by sending to this contract function() external payable { depositEther(); } function updateMaxErc20Deposit(uint256 maxDepositAmount) public onlyGovernance { require(maxDepositAmount != 0); emit MaxErc20DepositUpdate(maxErc20Deposit, maxDepositAmount); maxErc20Deposit = maxDepositAmount; } function transferAssets( address _token, address _user, uint256 _amountOrNFTId ) external isPredicateAuthorized { address wethToken = registry.getWethTokenAddress(); if (registry.isERC721(_token)) { IERC721(_token).transferFrom(address(this), _user, _amountOrNFTId); } else if (_token == wethToken) { WETH t = WETH(_token); t.withdraw(_amountOrNFTId, _user); } else { require(IERC20(_token).transfer(_user, _amountOrNFTId), "TRANSFER_FAILED"); } } function depositERC20(address _token, uint256 _amount) external { depositERC20ForUser(_token, msg.sender, _amount); } function depositERC721(address _token, uint256 _tokenId) external { depositERC721ForUser(_token, msg.sender, _tokenId); } function depositBulk( address[] calldata _tokens, uint256[] calldata _amountOrTokens, address _user ) external onlyWhenUnlocked // unlike other deposit functions, depositBulk doesn't invoke _safeCreateDepositBlock { require(_tokens.length == _amountOrTokens.length, "Invalid Input"); uint256 depositId = rootChain.updateDepositId(_tokens.length); Registry _registry = registry; for (uint256 i = 0; i < _tokens.length; i++) { // will revert if token is not mapped if (_registry.isTokenMappedAndIsErc721(_tokens[i])) { IERC721(_tokens[i]).transferFrom(msg.sender, address(this), _amountOrTokens[i]); } else { require( IERC20(_tokens[i]).transferFrom(msg.sender, address(this), _amountOrTokens[i]), "TOKEN_TRANSFER_FAILED" ); } _createDepositBlock(_user, _tokens[i], _amountOrTokens[i], depositId); depositId = depositId.add(1); } } /** * @dev Caches childChain and stateSender (frequently used variables) from registry */ function updateChildChainAndStateSender() public { (address _childChain, address _stateSender) = registry.getChildChainAndStateSender(); require( _stateSender != address(stateSender) || _childChain != childChain, "Atleast one of stateSender or childChain address should change" ); childChain = _childChain; stateSender = StateSender(_stateSender); } function depositERC20ForUser( address _token, address _user, uint256 _amount ) public { require(_amount <= maxErc20Deposit, "exceed maximum deposit amount"); require(IERC20(_token).transferFrom(msg.sender, address(this), _amount), "TOKEN_TRANSFER_FAILED"); _safeCreateDepositBlock(_user, _token, _amount); } function depositERC721ForUser( address _token, address _user, uint256 _tokenId ) public { IERC721(_token).transferFrom(msg.sender, address(this), _tokenId); _safeCreateDepositBlock(_user, _token, _tokenId); } // @todo: write depositEtherForUser function depositEther() public payable { address wethToken = registry.getWethTokenAddress(); WETH t = WETH(wethToken); t.deposit.value(msg.value)(); _safeCreateDepositBlock(msg.sender, wethToken, msg.value); } /** * @notice This will be invoked when safeTransferFrom is called on the token contract to deposit tokens to this contract without directly interacting with it * @dev msg.sender is the token contract * _operator The address which called `safeTransferFrom` function on the token contract * @param _user The address which previously owned the token * @param _tokenId The NFT identifier which is being transferred * _data Additional data with no specified format * @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` */ function onERC721Received( address, /* _operator */ address _user, uint256 _tokenId, bytes memory /* _data */ ) public returns (bytes4) { // the ERC721 contract address is the message sender _safeCreateDepositBlock( _user, msg.sender, /* token */ _tokenId ); return 0x150b7a02; } // See https://github.com/ethereum/EIPs/issues/223 function tokenFallback( address _user, uint256 _amount, bytes memory /* _data */ ) public { _safeCreateDepositBlock( _user, msg.sender, /* token */ _amount ); } function _safeCreateDepositBlock( address _user, address _token, uint256 _amountOrToken ) internal onlyWhenUnlocked isTokenMapped(_token) { _createDepositBlock( _user, _token, _amountOrToken, rootChain.updateDepositId(1) /* returns _depositId */ ); } function _createDepositBlock( address _user, address _token, uint256 _amountOrToken, uint256 _depositId ) internal { deposits[_depositId] = DepositBlock(keccak256(abi.encodePacked(_user, _token, _amountOrToken)), now); stateSender.syncState(childChain, abi.encode(_user, _token, _amountOrToken, _depositId)); emit NewDepositBlock(_user, _token, _amountOrToken, _depositId); } // Housekeeping function. @todo remove later function updateRootChain(address _rootChain) public onlyOwner { rootChain = RootChain(_rootChain); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":false,"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"depositERC721ForUser","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"updateChildChainAndStateSender","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"childChain","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_amountOrNFTId","type":"uint256"}],"name":"transferAssets","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"maxDepositAmount","type":"uint256"}],"name":"updateMaxErc20Deposit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"governance","outputs":[{"internalType":"contract IGovernance","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"registry","outputs":[{"internalType":"contract Registry","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"_tokens","type":"address[]"},{"internalType":"uint256[]","name":"_amountOrTokens","type":"uint256[]"},{"internalType":"address","name":"_user","type":"address"}],"name":"depositBulk","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"depositERC20ForUser","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":false,"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"depositERC20","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"rootChain","outputs":[{"internalType":"contract RootChain","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"depositEther","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"unlock","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"deposits","outputs":[{"internalType":"bytes32","name":"depositHash","type":"bytes32"},{"internalType":"uint256","name":"createdAt","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"tokenFallback","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"stateSender","outputs":[{"internalType":"contract StateSender","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"locked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"depositERC721","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"maxErc20Deposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_rootChain","type":"address"}],"name":"updateRootChain","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"lock","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountOrNFTId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"depositBlockId","type":"uint256"}],"name":"NewDepositBlock","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"oldLimit","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"newLimit","type":"uint256"}],"name":"MaxErc20DepositUpdate","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
608060405268056bc75e2d6310000060085534801561001d57600080fd5b50600080546001600160a01b031916331780825560405182916001600160a01b03169082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3600280546001600160a01b0319166001600160a01b0392909216919091179055506119eb806100976000396000f3fe6080604052600436106101815760003560e01c806397feb926116100d1578063cb10f94c1161008a578063e7af7ba111610064578063e7af7ba1146106d2578063f2203711146106f9578063f2fde38b1461072c578063f83d08ba1461075f57610181565b8063cb10f94c1461066f578063cf30901214610684578063d29a4bf61461069957610181565b806397feb92614610503578063987ab9db1461053c57806398ea5fca14610181578063a69df4b514610551578063b02c43d014610566578063c0ee0b8a146105a957610181565b80635aa6e6751161013e5780637b1f7117116101185780637b1f7117146103ae5780638b9e4f93146104825780638da5cb5b146104c55780638f32d59b146104da57610181565b80635aa6e6751461036f578063715018a6146103845780637b1039991461039957610181565b8063072b15351461018b578063150b7a02146101ce57806342be8379146102bc57806342fc47fb146102d157806349f4cc17146103025780634b56c07114610345575b610189610774565b005b34801561019757600080fd5b50610189600480360360608110156101ae57600080fd5b506001600160a01b03813581169160208101359091169060400135610856565b3480156101da57600080fd5b5061029f600480360360808110156101f157600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b81111561022b57600080fd5b82018360208201111561023d57600080fd5b803590602001918460018302840111600160201b8311171561025e57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506108d2945050505050565b604080516001600160e01b03199092168252519081900360200190f35b3480156102c857600080fd5b506101896108f0565b3480156102dd57600080fd5b506102e6610a01565b604080516001600160a01b039092168252519081900360200190f35b34801561030e57600080fd5b506101896004803603606081101561032557600080fd5b506001600160a01b03813581169160208101359091169060400135610a10565b34801561035157600080fd5b506101896004803603602081101561036857600080fd5b5035610da1565b34801561037b57600080fd5b506102e6610e28565b34801561039057600080fd5b50610189610e37565b3480156103a557600080fd5b506102e6610e92565b3480156103ba57600080fd5b50610189600480360360608110156103d157600080fd5b810190602081018135600160201b8111156103eb57600080fd5b8201836020820111156103fd57600080fd5b803590602001918460208302840111600160201b8311171561041e57600080fd5b919390929091602081019035600160201b81111561043b57600080fd5b82018360208201111561044d57600080fd5b803590602001918460208302840111600160201b8311171561046e57600080fd5b9193509150356001600160a01b0316610ea1565b34801561048e57600080fd5b50610189600480360360608110156104a557600080fd5b506001600160a01b038135811691602081013590911690604001356112a4565b3480156104d157600080fd5b506102e66113d0565b3480156104e657600080fd5b506104ef6113df565b604080519115158252519081900360200190f35b34801561050f57600080fd5b506101896004803603604081101561052657600080fd5b506001600160a01b0381351690602001356113f0565b34801561054857600080fd5b506102e66113fb565b34801561055d57600080fd5b5061018961140a565b34801561057257600080fd5b506105906004803603602081101561058957600080fd5b5035611462565b6040805192835260208301919091528051918290030190f35b3480156105b557600080fd5b50610189600480360360608110156105cc57600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b8111156105fb57600080fd5b82018360208201111561060d57600080fd5b803590602001918460018302840111600160201b8311171561062e57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061147b945050505050565b34801561067b57600080fd5b506102e6611486565b34801561069057600080fd5b506104ef611495565b3480156106a557600080fd5b50610189600480360360408110156106bc57600080fd5b506001600160a01b0381351690602001356114a5565b3480156106de57600080fd5b506106e76114b0565b60408051918252519081900360200190f35b34801561070557600080fd5b506101896004803603602081101561071c57600080fd5b50356001600160a01b03166114b6565b34801561073857600080fd5b506101896004803603602081101561074f57600080fd5b50356001600160a01b03166114e9565b34801561076b57600080fd5b50610189611506565b60035460408051638b9c948960e01b815290516000926001600160a01b031691638b9c9489916004808301926020929190829003018186803b1580156107b957600080fd5b505afa1580156107cd573d6000803e3d6000fd5b505050506040513d60208110156107e357600080fd5b505160408051630d0e30db60e41b8152905191925082916001600160a01b0383169163d0e30db091349160048082019260009290919082900301818588803b15801561082e57600080fd5b505af1158015610842573d6000803e3d6000fd5b5050505050610852338334611564565b5050565b604080516323b872dd60e01b81523360048201523060248201526044810183905290516001600160a01b038516916323b872dd91606480830192600092919082900301818387803b1580156108aa57600080fd5b505af11580156108be573d6000803e3d6000fd5b505050506108cd828483611564565b505050565b60006108df843385611564565b50630a85bd0160e11b949350505050565b60035460408051630c91702f60e31b8152815160009384936001600160a01b039091169263648b81789260048083019392829003018186803b15801561093557600080fd5b505afa158015610949573d6000803e3d6000fd5b505050506040513d604081101561095f57600080fd5b50805160209091015160055491935091506001600160a01b03808316911614158061099857506007546001600160a01b03838116911614155b6109d35760405162461bcd60e51b815260040180806020018281038252603e815260200180611953603e913960400191505060405180910390fd5b600780546001600160a01b039384166001600160a01b03199182161790915560058054929093169116179055565b6007546001600160a01b031681565b600354604080516337b1d58560e01b815233600482015290516001600160a01b03909216916337b1d58591602480820192602092909190829003018186803b158015610a5b57600080fd5b505afa158015610a6f573d6000803e3d6000fd5b505050506040513d6020811015610a8557600080fd5b50516003811115610a9257fe5b60ff16610ade576040805162461bcd60e51b81526020600482015260156024820152744e6f7420612076616c69642070726564696361746560581b604482015290519081900360640190fd5b60035460408051638b9c948960e01b815290516000926001600160a01b031691638b9c9489916004808301926020929190829003018186803b158015610b2357600080fd5b505afa158015610b37573d6000803e3d6000fd5b505050506040513d6020811015610b4d57600080fd5b5051600354604080516336a8279560e21b81526001600160a01b038881166004830152915193945091169163daa09e5491602480820192602092909190829003018186803b158015610b9e57600080fd5b505afa158015610bb2573d6000803e3d6000fd5b505050506040513d6020811015610bc857600080fd5b505115610c4457604080516323b872dd60e01b81523060048201526001600160a01b038581166024830152604482018590529151918616916323b872dd9160648082019260009290919082900301818387803b158015610c2757600080fd5b505af1158015610c3b573d6000803e3d6000fd5b50505050610d9b565b806001600160a01b0316846001600160a01b03161415610ccc5760408051627b8a6760e11b8152600481018490526001600160a01b0385811660248301529151869283169162f714ce91604480830192600092919082900301818387803b158015610cae57600080fd5b505af1158015610cc2573d6000803e3d6000fd5b5050505050610d9b565b836001600160a01b031663a9059cbb84846040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015610d2c57600080fd5b505af1158015610d40573d6000803e3d6000fd5b505050506040513d6020811015610d5657600080fd5b5051610d9b576040805162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b604482015290519081900360640190fd5b50505050565b6002546001600160a01b03163314610dea5760405162461bcd60e51b81526004018080602001828103825260268152602001806119916026913960400191505060405180910390fd5b80610df457600080fd5b6008546040518291907f010c0265813c273963aa5e8683cf5c45a3b744ba6369c22af0958ec5fcf16b2090600090a3600855565b6002546001600160a01b031681565b610e3f6113df565b610e4857600080fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6003546001600160a01b031681565b600254600160a01b900460ff1615610eec576040805162461bcd60e51b8152602060048201526009602482015268125cc8131bd8dad95960ba1b604482015290519081900360640190fd5b838214610f30576040805162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a5908125b9c1d5d609a1b604482015290519081900360640190fd5b6004805460408051635391f48360e01b8152928301879052516000926001600160a01b0390921691635391f48391602480830192602092919082900301818787803b158015610f7e57600080fd5b505af1158015610f92573d6000803e3d6000fd5b505050506040513d6020811015610fa857600080fd5b50516003549091506001600160a01b031660005b8681101561129a57816001600160a01b03166301f07db5898984818110610fdf57fe5b905060200201356001600160a01b03166040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561103557600080fd5b505afa158015611049573d6000803e3d6000fd5b505050506040513d602081101561105f57600080fd5b50511561112a5787878281811061107257fe5b905060200201356001600160a01b03166001600160a01b03166323b872dd333089898681811061109e57fe5b905060200201356040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050600060405180830381600087803b15801561110d57600080fd5b505af1158015611121573d6000803e3d6000fd5b50505050611246565b87878281811061113657fe5b905060200201356001600160a01b03166001600160a01b03166323b872dd333089898681811061116257fe5b905060200201356040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050602060405180830381600087803b1580156111d157600080fd5b505af11580156111e5573d6000803e3d6000fd5b505050506040513d60208110156111fb57600080fd5b5051611246576040805162461bcd60e51b81526020600482015260156024820152741513d2d15397d514905394d1915497d19052531151605a1b604482015290519081900360640190fd5b61127f8489898481811061125657fe5b905060200201356001600160a01b031688888581811061127257fe5b9050602002013586611701565b61129083600163ffffffff6118cb16565b9250600101610fbc565b5050505050505050565b6008548111156112fb576040805162461bcd60e51b815260206004820152601d60248201527f657863656564206d6178696d756d206465706f73697420616d6f756e74000000604482015290519081900360640190fd5b604080516323b872dd60e01b81523360048201523060248201526044810183905290516001600160a01b038516916323b872dd9160648083019260209291908290030181600087803b15801561135057600080fd5b505af1158015611364573d6000803e3d6000fd5b505050506040513d602081101561137a57600080fd5b50516113c5576040805162461bcd60e51b81526020600482015260156024820152741513d2d15397d514905394d1915497d19052531151605a1b604482015290519081900360640190fd5b6108cd828483611564565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b6108528233836112a4565b6004546001600160a01b031681565b6002546001600160a01b031633146114535760405162461bcd60e51b81526004018080602001828103825260268152602001806119916026913960400191505060405180910390fd5b6002805460ff60a01b19169055565b6006602052600090815260409020805460019091015482565b6108cd833384611564565b6005546001600160a01b031681565b600254600160a01b900460ff1681565b610852823383610856565b60085481565b6114be6113df565b6114c757600080fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6114f16113df565b6114fa57600080fd5b611503816118e4565b50565b6002546001600160a01b0316331461154f5760405162461bcd60e51b81526004018080602001828103825260268152602001806119916026913960400191505060405180910390fd5b6002805460ff60a01b1916600160a01b179055565b600254600160a01b900460ff16156115af576040805162461bcd60e51b8152602060048201526009602482015268125cc8131bd8dad95960ba1b604482015290519081900360640190fd5b60035460408051636416c18360e01b81526001600160a01b038086166004830152915185939290921691636416c18391602480820192602092909190829003018186803b1580156115ff57600080fd5b505afa158015611613573d6000803e3d6000fd5b505050506040513d602081101561162957600080fd5b5051611672576040805162461bcd60e51b81526020600482015260136024820152721513d2d15397d393d517d4d5541413d4951151606a1b604482015290519081900360640190fd5b610d9b848484600460009054906101000a90046001600160a01b03166001600160a01b0316635391f48360016040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156116d457600080fd5b505af11580156116e8573d6000803e3d6000fd5b505050506040513d60208110156116fe57600080fd5b50515b604080518082018252606086811b6bffffffffffffffffffffffff199081168284015286821b16607483015260888083018690528351808403909101815260a883018452805160209182012083524281840190815260008681526006835285812094518555905160019094019390935560055460075485516001600160a01b03808c1682860152808b168289015294810189905260808082018990528751808303909101815260a082018089526316f1983160e01b905291851660a4820181815260c48301988952835160e4840152835196909416976316f198319791969395909361010490930192908601918190849084905b8381101561180d5781810151838201526020016117f5565b50505050905090810190601f16801561183a5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561185a57600080fd5b505af115801561186e573d6000803e3d6000fd5b50505050826001600160a01b0316846001600160a01b03167f1dadc8d0683c6f9824e885935c1bec6f76816730dcec148dda8cf25a7b9f797b8484604051808381526020018281526020019250505060405180910390a350505050565b6000828201838110156118dd57600080fd5b9392505050565b6001600160a01b0381166118f757600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b039290921691909117905556fe41746c65617374206f6e65206f6620737461746553656e646572206f72206368696c64436861696e20616464726573732073686f756c64206368616e67654f6e6c7920676f7665726e616e636520636f6e747261637420697320617574686f72697a6564a265627a7a72315820fa168237dcd05ed8461c994d8861a355492d574384104275b68d06cf6264c4ac64736f6c634300050b0032
Deployed Bytecode
0x6080604052600436106101815760003560e01c806397feb926116100d1578063cb10f94c1161008a578063e7af7ba111610064578063e7af7ba1146106d2578063f2203711146106f9578063f2fde38b1461072c578063f83d08ba1461075f57610181565b8063cb10f94c1461066f578063cf30901214610684578063d29a4bf61461069957610181565b806397feb92614610503578063987ab9db1461053c57806398ea5fca14610181578063a69df4b514610551578063b02c43d014610566578063c0ee0b8a146105a957610181565b80635aa6e6751161013e5780637b1f7117116101185780637b1f7117146103ae5780638b9e4f93146104825780638da5cb5b146104c55780638f32d59b146104da57610181565b80635aa6e6751461036f578063715018a6146103845780637b1039991461039957610181565b8063072b15351461018b578063150b7a02146101ce57806342be8379146102bc57806342fc47fb146102d157806349f4cc17146103025780634b56c07114610345575b610189610774565b005b34801561019757600080fd5b50610189600480360360608110156101ae57600080fd5b506001600160a01b03813581169160208101359091169060400135610856565b3480156101da57600080fd5b5061029f600480360360808110156101f157600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b81111561022b57600080fd5b82018360208201111561023d57600080fd5b803590602001918460018302840111600160201b8311171561025e57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506108d2945050505050565b604080516001600160e01b03199092168252519081900360200190f35b3480156102c857600080fd5b506101896108f0565b3480156102dd57600080fd5b506102e6610a01565b604080516001600160a01b039092168252519081900360200190f35b34801561030e57600080fd5b506101896004803603606081101561032557600080fd5b506001600160a01b03813581169160208101359091169060400135610a10565b34801561035157600080fd5b506101896004803603602081101561036857600080fd5b5035610da1565b34801561037b57600080fd5b506102e6610e28565b34801561039057600080fd5b50610189610e37565b3480156103a557600080fd5b506102e6610e92565b3480156103ba57600080fd5b50610189600480360360608110156103d157600080fd5b810190602081018135600160201b8111156103eb57600080fd5b8201836020820111156103fd57600080fd5b803590602001918460208302840111600160201b8311171561041e57600080fd5b919390929091602081019035600160201b81111561043b57600080fd5b82018360208201111561044d57600080fd5b803590602001918460208302840111600160201b8311171561046e57600080fd5b9193509150356001600160a01b0316610ea1565b34801561048e57600080fd5b50610189600480360360608110156104a557600080fd5b506001600160a01b038135811691602081013590911690604001356112a4565b3480156104d157600080fd5b506102e66113d0565b3480156104e657600080fd5b506104ef6113df565b604080519115158252519081900360200190f35b34801561050f57600080fd5b506101896004803603604081101561052657600080fd5b506001600160a01b0381351690602001356113f0565b34801561054857600080fd5b506102e66113fb565b34801561055d57600080fd5b5061018961140a565b34801561057257600080fd5b506105906004803603602081101561058957600080fd5b5035611462565b6040805192835260208301919091528051918290030190f35b3480156105b557600080fd5b50610189600480360360608110156105cc57600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b8111156105fb57600080fd5b82018360208201111561060d57600080fd5b803590602001918460018302840111600160201b8311171561062e57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061147b945050505050565b34801561067b57600080fd5b506102e6611486565b34801561069057600080fd5b506104ef611495565b3480156106a557600080fd5b50610189600480360360408110156106bc57600080fd5b506001600160a01b0381351690602001356114a5565b3480156106de57600080fd5b506106e76114b0565b60408051918252519081900360200190f35b34801561070557600080fd5b506101896004803603602081101561071c57600080fd5b50356001600160a01b03166114b6565b34801561073857600080fd5b506101896004803603602081101561074f57600080fd5b50356001600160a01b03166114e9565b34801561076b57600080fd5b50610189611506565b60035460408051638b9c948960e01b815290516000926001600160a01b031691638b9c9489916004808301926020929190829003018186803b1580156107b957600080fd5b505afa1580156107cd573d6000803e3d6000fd5b505050506040513d60208110156107e357600080fd5b505160408051630d0e30db60e41b8152905191925082916001600160a01b0383169163d0e30db091349160048082019260009290919082900301818588803b15801561082e57600080fd5b505af1158015610842573d6000803e3d6000fd5b5050505050610852338334611564565b5050565b604080516323b872dd60e01b81523360048201523060248201526044810183905290516001600160a01b038516916323b872dd91606480830192600092919082900301818387803b1580156108aa57600080fd5b505af11580156108be573d6000803e3d6000fd5b505050506108cd828483611564565b505050565b60006108df843385611564565b50630a85bd0160e11b949350505050565b60035460408051630c91702f60e31b8152815160009384936001600160a01b039091169263648b81789260048083019392829003018186803b15801561093557600080fd5b505afa158015610949573d6000803e3d6000fd5b505050506040513d604081101561095f57600080fd5b50805160209091015160055491935091506001600160a01b03808316911614158061099857506007546001600160a01b03838116911614155b6109d35760405162461bcd60e51b815260040180806020018281038252603e815260200180611953603e913960400191505060405180910390fd5b600780546001600160a01b039384166001600160a01b03199182161790915560058054929093169116179055565b6007546001600160a01b031681565b600354604080516337b1d58560e01b815233600482015290516001600160a01b03909216916337b1d58591602480820192602092909190829003018186803b158015610a5b57600080fd5b505afa158015610a6f573d6000803e3d6000fd5b505050506040513d6020811015610a8557600080fd5b50516003811115610a9257fe5b60ff16610ade576040805162461bcd60e51b81526020600482015260156024820152744e6f7420612076616c69642070726564696361746560581b604482015290519081900360640190fd5b60035460408051638b9c948960e01b815290516000926001600160a01b031691638b9c9489916004808301926020929190829003018186803b158015610b2357600080fd5b505afa158015610b37573d6000803e3d6000fd5b505050506040513d6020811015610b4d57600080fd5b5051600354604080516336a8279560e21b81526001600160a01b038881166004830152915193945091169163daa09e5491602480820192602092909190829003018186803b158015610b9e57600080fd5b505afa158015610bb2573d6000803e3d6000fd5b505050506040513d6020811015610bc857600080fd5b505115610c4457604080516323b872dd60e01b81523060048201526001600160a01b038581166024830152604482018590529151918616916323b872dd9160648082019260009290919082900301818387803b158015610c2757600080fd5b505af1158015610c3b573d6000803e3d6000fd5b50505050610d9b565b806001600160a01b0316846001600160a01b03161415610ccc5760408051627b8a6760e11b8152600481018490526001600160a01b0385811660248301529151869283169162f714ce91604480830192600092919082900301818387803b158015610cae57600080fd5b505af1158015610cc2573d6000803e3d6000fd5b5050505050610d9b565b836001600160a01b031663a9059cbb84846040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015610d2c57600080fd5b505af1158015610d40573d6000803e3d6000fd5b505050506040513d6020811015610d5657600080fd5b5051610d9b576040805162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b604482015290519081900360640190fd5b50505050565b6002546001600160a01b03163314610dea5760405162461bcd60e51b81526004018080602001828103825260268152602001806119916026913960400191505060405180910390fd5b80610df457600080fd5b6008546040518291907f010c0265813c273963aa5e8683cf5c45a3b744ba6369c22af0958ec5fcf16b2090600090a3600855565b6002546001600160a01b031681565b610e3f6113df565b610e4857600080fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6003546001600160a01b031681565b600254600160a01b900460ff1615610eec576040805162461bcd60e51b8152602060048201526009602482015268125cc8131bd8dad95960ba1b604482015290519081900360640190fd5b838214610f30576040805162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a5908125b9c1d5d609a1b604482015290519081900360640190fd5b6004805460408051635391f48360e01b8152928301879052516000926001600160a01b0390921691635391f48391602480830192602092919082900301818787803b158015610f7e57600080fd5b505af1158015610f92573d6000803e3d6000fd5b505050506040513d6020811015610fa857600080fd5b50516003549091506001600160a01b031660005b8681101561129a57816001600160a01b03166301f07db5898984818110610fdf57fe5b905060200201356001600160a01b03166040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561103557600080fd5b505afa158015611049573d6000803e3d6000fd5b505050506040513d602081101561105f57600080fd5b50511561112a5787878281811061107257fe5b905060200201356001600160a01b03166001600160a01b03166323b872dd333089898681811061109e57fe5b905060200201356040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050600060405180830381600087803b15801561110d57600080fd5b505af1158015611121573d6000803e3d6000fd5b50505050611246565b87878281811061113657fe5b905060200201356001600160a01b03166001600160a01b03166323b872dd333089898681811061116257fe5b905060200201356040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050602060405180830381600087803b1580156111d157600080fd5b505af11580156111e5573d6000803e3d6000fd5b505050506040513d60208110156111fb57600080fd5b5051611246576040805162461bcd60e51b81526020600482015260156024820152741513d2d15397d514905394d1915497d19052531151605a1b604482015290519081900360640190fd5b61127f8489898481811061125657fe5b905060200201356001600160a01b031688888581811061127257fe5b9050602002013586611701565b61129083600163ffffffff6118cb16565b9250600101610fbc565b5050505050505050565b6008548111156112fb576040805162461bcd60e51b815260206004820152601d60248201527f657863656564206d6178696d756d206465706f73697420616d6f756e74000000604482015290519081900360640190fd5b604080516323b872dd60e01b81523360048201523060248201526044810183905290516001600160a01b038516916323b872dd9160648083019260209291908290030181600087803b15801561135057600080fd5b505af1158015611364573d6000803e3d6000fd5b505050506040513d602081101561137a57600080fd5b50516113c5576040805162461bcd60e51b81526020600482015260156024820152741513d2d15397d514905394d1915497d19052531151605a1b604482015290519081900360640190fd5b6108cd828483611564565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b6108528233836112a4565b6004546001600160a01b031681565b6002546001600160a01b031633146114535760405162461bcd60e51b81526004018080602001828103825260268152602001806119916026913960400191505060405180910390fd5b6002805460ff60a01b19169055565b6006602052600090815260409020805460019091015482565b6108cd833384611564565b6005546001600160a01b031681565b600254600160a01b900460ff1681565b610852823383610856565b60085481565b6114be6113df565b6114c757600080fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6114f16113df565b6114fa57600080fd5b611503816118e4565b50565b6002546001600160a01b0316331461154f5760405162461bcd60e51b81526004018080602001828103825260268152602001806119916026913960400191505060405180910390fd5b6002805460ff60a01b1916600160a01b179055565b600254600160a01b900460ff16156115af576040805162461bcd60e51b8152602060048201526009602482015268125cc8131bd8dad95960ba1b604482015290519081900360640190fd5b60035460408051636416c18360e01b81526001600160a01b038086166004830152915185939290921691636416c18391602480820192602092909190829003018186803b1580156115ff57600080fd5b505afa158015611613573d6000803e3d6000fd5b505050506040513d602081101561162957600080fd5b5051611672576040805162461bcd60e51b81526020600482015260136024820152721513d2d15397d393d517d4d5541413d4951151606a1b604482015290519081900360640190fd5b610d9b848484600460009054906101000a90046001600160a01b03166001600160a01b0316635391f48360016040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156116d457600080fd5b505af11580156116e8573d6000803e3d6000fd5b505050506040513d60208110156116fe57600080fd5b50515b604080518082018252606086811b6bffffffffffffffffffffffff199081168284015286821b16607483015260888083018690528351808403909101815260a883018452805160209182012083524281840190815260008681526006835285812094518555905160019094019390935560055460075485516001600160a01b03808c1682860152808b168289015294810189905260808082018990528751808303909101815260a082018089526316f1983160e01b905291851660a4820181815260c48301988952835160e4840152835196909416976316f198319791969395909361010490930192908601918190849084905b8381101561180d5781810151838201526020016117f5565b50505050905090810190601f16801561183a5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561185a57600080fd5b505af115801561186e573d6000803e3d6000fd5b50505050826001600160a01b0316846001600160a01b03167f1dadc8d0683c6f9824e885935c1bec6f76816730dcec148dda8cf25a7b9f797b8484604051808381526020018281526020019250505060405180910390a350505050565b6000828201838110156118dd57600080fd5b9392505050565b6001600160a01b0381166118f757600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b039290921691909117905556fe41746c65617374206f6e65206f6620737461746553656e646572206f72206368696c64436861696e20616464726573732073686f756c64206368616e67654f6e6c7920676f7665726e616e636520636f6e747261637420697320617574686f72697a6564a265627a7a72315820fa168237dcd05ed8461c994d8861a355492d574384104275b68d06cf6264c4ac64736f6c634300050b0032
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.