Source Code
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
DepositManager
Compiler Version
v0.5.17+commit.d19bba13
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2021-09-17
*/
// 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/token/ERC721/ERC721Holder.sol
pragma solidity ^0.5.2;
contract ERC721Holder is IERC721Receiver {
function onERC721Received(address, address, uint256, bytes memory) public returns (bytes4) {
return this.onERC721Received.selector;
}
}
// File: openzeppelin-solidity/contracts/token/ERC20/IERC20.sol
pragma solidity ^0.5.2;
/**
* @title ERC20 interface
* @dev see https://eips.ethereum.org/EIPS/eip-20
*/
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);
}
// 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/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: 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/token/ERC20/SafeERC20.sol
pragma solidity ^0.5.2;
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using SafeMath for uint256;
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require((value == 0) || (token.allowance(address(this), spender) == 0));
callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).add(value);
callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).sub(value);
callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must equal true).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves.
// A Solidity high level call has three parts:
// 1. The target address is checked to verify it contains contract code
// 2. The call itself is made, and success asserted
// 3. The return value is decoded, which in turn checks the size of the returned data.
require(address(token).isContract());
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = address(token).call(data);
require(success);
if (returndata.length > 0) { // Return data is optional
require(abi.decode(returndata, (bool)));
}
}
}
// 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() {
_assertGovernance();
_;
}
function _assertGovernance() private view {
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/token/ERC20/ERC20.sol
pragma solidity ^0.5.2;
/**
* @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));
}
}
// File: contracts/common/tokens/WETH.sol
pragma solidity ^0.5.2;
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;
}
// File: contracts/root/depositManager/IDepositManager.sol
pragma solidity ^0.5.2;
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;
}
// 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 {
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))
}
}
}
// 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/mixin/ChainIdMixin.sol
pragma solidity ^0.5.2;
contract ChainIdMixin {
bytes constant public networkId = hex"3A99";
uint256 constant public CHAINID = 15001;
}
// 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.17;
contract IStakeManager {
// validator replacement
function startAuction(
uint256 validatorId,
uint256 amount,
bool acceptDelegation,
bytes calldata signerPubkey
) external;
function confirmAuctionBid(uint256 validatorId, uint256 heimdallFee) external;
function transferFunds(
uint256 validatorId,
uint256 amount,
address delegator
) external returns (bool);
function delegationDeposit(
uint256 validatorId,
uint256 amount,
address delegator
) external returns (bool);
function unstake(uint256 validatorId) external;
function totalStakedFor(address addr) external view returns (uint256);
function stakeFor(
address user,
uint256 amount,
uint256 heimdallFee,
bool acceptDelegation,
bytes memory signerPubkey
) public;
function checkSignatures(
uint256 blockInterval,
bytes32 voteHash,
bytes32 stateRoot,
address proposer,
uint[3][] calldata sigs
) external returns (uint256);
function updateValidatorState(uint256 validatorId, int256 amount) public;
function ownerOf(uint256 tokenId) public view returns (address);
function slash(bytes calldata slashingInfoList) external returns (uint256);
function validatorStake(uint256 validatorId) public view returns (uint256);
function epoch() public view returns (uint256);
function getRegistry() public view returns (address);
function withdrawalDelay() public view returns (uint256);
function delegatedAmount(uint256 validatorId) public view returns(uint256);
function decreaseValidatorDelegatedAmount(uint256 validatorId, uint256 amount) public;
function withdrawDelegatorsReward(uint256 validatorId) public returns(uint256);
function delegatorsReward(uint256 validatorId) public view returns(uint256);
function dethroneAndStake(
address auctionUser,
uint256 heimdallFee,
uint256 validatorId,
uint256 auctionAmount,
bool acceptDelegation,
bytes calldata signerPubkey
) external;
}
// 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 submitCheckpoint(bytes calldata data, uint[3][] 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 {
revert();
}
function submitCheckpoint(bytes calldata data, uint[3][] 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: contracts/root/stateSyncer/StateSender.sol
pragma solidity ^0.5.2;
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);
}
}
}
// File: contracts/common/mixin/Lockable.sol
pragma solidity ^0.5.2;
contract Lockable {
bool public locked;
modifier onlyWhenUnlocked() {
_assertUnlocked();
_;
}
function _assertUnlocked() private view {
require(!locked, "locked");
}
function lock() public {
locked = true;
}
function unlock() public {
locked = false;
}
}
// File: contracts/common/mixin/GovernanceLockable.sol
pragma solidity ^0.5.2;
contract GovernanceLockable is Lockable, Governable {
constructor(address governance) public Governable(governance) {}
function lock() public onlyGovernance {
super.lock();
}
function unlock() public onlyGovernance {
super.unlock();
}
}
// File: contracts/root/depositManager/DepositManagerStorage.sol
pragma solidity ^0.5.2;
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, GovernanceLockable, DepositManagerHeader {
Registry public registry;
RootChain public rootChain;
StateSender public stateSender;
mapping(uint256 => DepositBlock) public deposits;
address public childChain;
uint256 public maxErc20Deposit = 100 * (10**18);
}
// File: contracts/root/depositManager/DepositManager.sol
pragma solidity ^0.5.2;
contract DepositManager is DepositManagerStorage, IDepositManager, ERC721Holder {
using SafeMath for uint256;
using SafeERC20 for IERC20;
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 GovernanceLockable(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])) {
_safeTransferERC721(msg.sender, _tokens[i], _amountOrTokens[i]);
} else {
IERC20(_tokens[i]).safeTransferFrom(msg.sender, address(this), _amountOrTokens[i]);
}
_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");
IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);
_safeCreateDepositBlock(_user, _token, _amount);
}
function depositERC721ForUser(
address _token,
address _user,
uint256 _tokenId
) public {
require(registry.isTokenMappedAndIsErc721(_token), "not erc721");
_safeTransferERC721(msg.sender, _token, _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);
}
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);
}
function _safeTransferERC721(address _user, address _token, uint256 _tokenId) private {
IERC721(_token).safeTransferFrom(_user, address(this), _tokenId);
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"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":"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":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":true,"inputs":[],"name":"childChain","outputs":[{"internalType":"address","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":"uint256","name":"_amount","type":"uint256"}],"name":"depositERC20","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":false,"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"depositERC721","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":"_tokenId","type":"uint256"}],"name":"depositERC721ForUser","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"depositEther","outputs":[],"payable":true,"stateMutability":"payable","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":true,"inputs":[],"name":"governance","outputs":[{"internalType":"contract IGovernance","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":[],"name":"lock","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"locked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","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":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"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":"registry","outputs":[{"internalType":"contract Registry","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":"rootChain","outputs":[{"internalType":"contract RootChain","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"stateSender","outputs":[{"internalType":"contract StateSender","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":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"unlock","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"updateChildChainAndStateSender","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":false,"inputs":[{"internalType":"address","name":"_rootChain","type":"address"}],"name":"updateRootChain","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
608060405268056bc75e2d6310000060085534801561001d57600080fd5b50600080546001600160a01b031916331780825560405182916001600160a01b03169082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3600280546001600160a01b0319166001600160a01b039290921691909117905550611866806100976000396000f3fe6080604052600436106101665760003560e01c80638f32d59b116100d1578063cb10f94c1161008a578063e7af7ba111610064578063e7af7ba1146105f7578063f22037111461061e578063f2fde38b14610651578063f83d08ba1461068457610166565b8063cb10f94c14610594578063cf309012146105a9578063d29a4bf6146105be57610166565b80638f32d59b146104c557806397feb926146104ee578063987ab9db1461052757806398ea5fca14610166578063a69df4b51461053c578063b02c43d01461055157610166565b80635aa6e675116101235780635aa6e67514610356578063715018a61461036b5780637b103999146103805780637b1f7117146103955780638b9e4f931461046d5780638da5cb5b146104b057610166565b8063072b153514610170578063150b7a02146101b357806342be8379146102a357806342fc47fb146102b857806349f4cc17146102e95780634b56c0711461032c575b61016e610699565b005b34801561017c57600080fd5b5061016e6004803603606081101561019357600080fd5b506001600160a01b0381358116916020810135909116906040013561077b565b3480156101bf57600080fd5b50610286600480360360808110156101d657600080fd5b6001600160a01b0382358116926020810135909116916040820135919081019060808101606082013564010000000081111561021157600080fd5b82018360208201111561022357600080fd5b8035906020019184600183028401116401000000008311171561024557600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061084d945050505050565b604080516001600160e01b03199092168252519081900360200190f35b3480156102af57600080fd5b5061016e61085d565b3480156102c457600080fd5b506102cd61096e565b604080516001600160a01b039092168252519081900360200190f35b3480156102f557600080fd5b5061016e6004803603606081101561030c57600080fd5b506001600160a01b0381358116916020810135909116906040013561097d565b34801561033857600080fd5b5061016e6004803603602081101561034f57600080fd5b5035610d0e565b34801561036257600080fd5b506102cd610d54565b34801561037757600080fd5b5061016e610d63565b34801561038c57600080fd5b506102cd610dbe565b3480156103a157600080fd5b5061016e600480360360608110156103b857600080fd5b8101906020810181356401000000008111156103d357600080fd5b8201836020820111156103e557600080fd5b8035906020019184602083028401116401000000008311171561040757600080fd5b91939092909160208101903564010000000081111561042557600080fd5b82018360208201111561043757600080fd5b8035906020019184602083028401116401000000008311171561045957600080fd5b9193509150356001600160a01b0316610dcd565b34801561047957600080fd5b5061016e6004803603606081101561049057600080fd5b506001600160a01b03813581169160208101359091169060400135611037565b3480156104bc57600080fd5b506102cd6110a9565b3480156104d157600080fd5b506104da6110b8565b604080519115158252519081900360200190f35b3480156104fa57600080fd5b5061016e6004803603604081101561051157600080fd5b506001600160a01b0381351690602001356110c9565b34801561053357600080fd5b506102cd6110d4565b34801561054857600080fd5b5061016e6110e3565b34801561055d57600080fd5b5061057b6004803603602081101561057457600080fd5b50356110f5565b6040805192835260208301919091528051918290030190f35b3480156105a057600080fd5b506102cd61110e565b3480156105b557600080fd5b506104da61111d565b3480156105ca57600080fd5b5061016e600480360360408110156105e157600080fd5b506001600160a01b03813516906020013561112d565b34801561060357600080fd5b5061060c611138565b60408051918252519081900360200190f35b34801561062a57600080fd5b5061016e6004803603602081101561064157600080fd5b50356001600160a01b031661113e565b34801561065d57600080fd5b5061016e6004803603602081101561067457600080fd5b50356001600160a01b0316611171565b34801561069057600080fd5b5061016e61118e565b60035460408051638b9c948960e01b815290516000926001600160a01b031691638b9c9489916004808301926020929190829003018186803b1580156106de57600080fd5b505afa1580156106f2573d6000803e3d6000fd5b505050506040513d602081101561070857600080fd5b505160408051630d0e30db60e41b8152905191925082916001600160a01b0383169163d0e30db091349160048082019260009290919082900301818588803b15801561075357600080fd5b505af1158015610767573d6000803e3d6000fd5b505050505061077733833461119e565b5050565b600354604080516301f07db560e01b81526001600160a01b038681166004830152915191909216916301f07db5916024808301926020929190829003018186803b1580156107c857600080fd5b505afa1580156107dc573d6000803e3d6000fd5b505050506040513d60208110156107f257600080fd5b5051610832576040805162461bcd60e51b815260206004820152600a6024820152696e6f742065726337323160b01b604482015290519081900360640190fd5b61083d3384836112fc565b61084882848361119e565b505050565b630a85bd0160e11b949350505050565b60035460408051630c91702f60e31b8152815160009384936001600160a01b039091169263648b81789260048083019392829003018186803b1580156108a257600080fd5b505afa1580156108b6573d6000803e3d6000fd5b505050506040513d60408110156108cc57600080fd5b50805160209091015160055491935091506001600160a01b03808316911614158061090557506007546001600160a01b03838116911614155b6109405760405162461bcd60e51b815260040180806020018281038252603e8152602001806117ce603e913960400191505060405180910390fd5b600780546001600160a01b039384166001600160a01b03199182161790915560058054929093169116179055565b6007546001600160a01b031681565b600354604080516337b1d58560e01b815233600482015290516001600160a01b03909216916337b1d58591602480820192602092909190829003018186803b1580156109c857600080fd5b505afa1580156109dc573d6000803e3d6000fd5b505050506040513d60208110156109f257600080fd5b505160038111156109ff57fe5b60ff16610a4b576040805162461bcd60e51b81526020600482015260156024820152744e6f7420612076616c69642070726564696361746560581b604482015290519081900360640190fd5b60035460408051638b9c948960e01b815290516000926001600160a01b031691638b9c9489916004808301926020929190829003018186803b158015610a9057600080fd5b505afa158015610aa4573d6000803e3d6000fd5b505050506040513d6020811015610aba57600080fd5b5051600354604080516336a8279560e21b81526001600160a01b038881166004830152915193945091169163daa09e5491602480820192602092909190829003018186803b158015610b0b57600080fd5b505afa158015610b1f573d6000803e3d6000fd5b505050506040513d6020811015610b3557600080fd5b505115610bb157604080516323b872dd60e01b81523060048201526001600160a01b038581166024830152604482018590529151918616916323b872dd9160648082019260009290919082900301818387803b158015610b9457600080fd5b505af1158015610ba8573d6000803e3d6000fd5b50505050610d08565b806001600160a01b0316846001600160a01b03161415610c395760408051627b8a6760e11b8152600481018490526001600160a01b0385811660248301529151869283169162f714ce91604480830192600092919082900301818387803b158015610c1b57600080fd5b505af1158015610c2f573d6000803e3d6000fd5b5050505050610d08565b836001600160a01b031663a9059cbb84846040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015610c9957600080fd5b505af1158015610cad573d6000803e3d6000fd5b505050506040513d6020811015610cc357600080fd5b5051610d08576040805162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b604482015290519081900360640190fd5b50505050565b610d16611371565b80610d2057600080fd5b6008546040518291907f010c0265813c273963aa5e8683cf5c45a3b744ba6369c22af0958ec5fcf16b2090600090a3600855565b6002546001600160a01b031681565b610d6b6110b8565b610d7457600080fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6003546001600160a01b031681565b610dd56113ba565b838214610e19576040805162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a5908125b9c1d5d609a1b604482015290519081900360640190fd5b6004805460408051635391f48360e01b8152928301879052516000926001600160a01b0390921691635391f48391602480830192602092919082900301818787803b158015610e6757600080fd5b505af1158015610e7b573d6000803e3d6000fd5b505050506040513d6020811015610e9157600080fd5b50516003549091506001600160a01b031660005b8681101561102d57816001600160a01b03166301f07db5898984818110610ec857fe5b905060200201356001600160a01b03166040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610f1e57600080fd5b505afa158015610f32573d6000803e3d6000fd5b505050506040513d6020811015610f4857600080fd5b505115610f8c57610f8733898984818110610f5f57fe5b905060200201356001600160a01b0316888885818110610f7b57fe5b905060200201356112fc565b610fd9565b610fd93330888885818110610f9d57fe5b905060200201358b8b86818110610fb057fe5b905060200201356001600160a01b03166001600160a01b0316611402909392919063ffffffff16565b61101284898984818110610fe957fe5b905060200201356001600160a01b031688888581811061100557fe5b905060200201358661145c565b61102383600163ffffffff61162616565b9250600101610ea5565b5050505050505050565b60085481111561108e576040805162461bcd60e51b815260206004820152601d60248201527f657863656564206d6178696d756d206465706f73697420616d6f756e74000000604482015290519081900360640190fd5b61083d6001600160a01b03841633308463ffffffff61140216565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b610777823383611037565b6004546001600160a01b031681565b6110eb611371565b6110f361163f565b565b6006602052600090815260409020805460019091015482565b6005546001600160a01b031681565b600154600160a01b900460ff1681565b61077782338361077b565b60085481565b6111466110b8565b61114f57600080fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6111796110b8565b61118257600080fd5b61118b8161164e565b50565b611196611371565b6110f36116bc565b6111a66113ba565b60035460408051636416c18360e01b81526001600160a01b038086166004830152915185939290921691636416c18391602480820192602092909190829003018186803b1580156111f657600080fd5b505afa15801561120a573d6000803e3d6000fd5b505050506040513d602081101561122057600080fd5b5051611269576040805162461bcd60e51b81526020600482015260136024820152721513d2d15397d393d517d4d5541413d4951151606a1b604482015290519081900360640190fd5b610d08848484600460009054906101000a90046001600160a01b03166001600160a01b0316635391f48360016040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156112cb57600080fd5b505af11580156112df573d6000803e3d6000fd5b505050506040513d60208110156112f557600080fd5b505161145c565b60408051632142170760e11b81526001600160a01b038581166004830152306024830152604482018490529151918416916342842e0e9160648082019260009290919082900301818387803b15801561135457600080fd5b505af1158015611368573d6000803e3d6000fd5b50505050505050565b6002546001600160a01b031633146110f35760405162461bcd60e51b815260040180806020018281038252602681526020018061180c6026913960400191505060405180910390fd5b600154600160a01b900460ff16156110f3576040805162461bcd60e51b81526020600482015260066024820152651b1bd8dad95960d21b604482015290519081900360640190fd5b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052610d089085906116d1565b604080518082018252606086811b6bffffffffffffffffffffffff199081168284015286821b16607483015260888083018690528351808403909101815260a883018452805160209182012083524281840190815260008681526006835285812094518555905160019094019390935560055460075485516001600160a01b03808c1682860152808b168289015294810189905260808082018990528751808303909101815260a082018089526316f1983160e01b905291851660a4820181815260c48301988952835160e4840152835196909416976316f198319791969395909361010490930192908601918190849084905b83811015611568578181015183820152602001611550565b50505050905090810190601f1680156115955780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156115b557600080fd5b505af11580156115c9573d6000803e3d6000fd5b50505050826001600160a01b0316846001600160a01b03167f1dadc8d0683c6f9824e885935c1bec6f76816730dcec148dda8cf25a7b9f797b8484604051808381526020018281526020019250505060405180910390a350505050565b60008282018381101561163857600080fd5b9392505050565b6001805460ff60a01b19169055565b6001600160a01b03811661166157600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6001805460ff60a01b1916600160a01b179055565b6116e3826001600160a01b03166117c7565b6116ec57600080fd5b60006060836001600160a01b0316836040518082805190602001908083835b6020831061172a5780518252601f19909201916020918201910161170b565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461178c576040519150601f19603f3d011682016040523d82523d6000602084013e611791565b606091505b5091509150816117a057600080fd5b805115610d08578080602001905160208110156117bc57600080fd5b5051610d0857600080fd5b3b15159056fe41746c65617374206f6e65206f6620737461746553656e646572206f72206368696c64436861696e20616464726573732073686f756c64206368616e67654f6e6c7920676f7665726e616e636520636f6e747261637420697320617574686f72697a6564a265627a7a72315820b7ba4e5c5ee8a4a1915dfdf1d9929499a44c1cfff1f0a55c5119cdc6b39b506b64736f6c63430005110032
Deployed Bytecode
0x6080604052600436106101665760003560e01c80638f32d59b116100d1578063cb10f94c1161008a578063e7af7ba111610064578063e7af7ba1146105f7578063f22037111461061e578063f2fde38b14610651578063f83d08ba1461068457610166565b8063cb10f94c14610594578063cf309012146105a9578063d29a4bf6146105be57610166565b80638f32d59b146104c557806397feb926146104ee578063987ab9db1461052757806398ea5fca14610166578063a69df4b51461053c578063b02c43d01461055157610166565b80635aa6e675116101235780635aa6e67514610356578063715018a61461036b5780637b103999146103805780637b1f7117146103955780638b9e4f931461046d5780638da5cb5b146104b057610166565b8063072b153514610170578063150b7a02146101b357806342be8379146102a357806342fc47fb146102b857806349f4cc17146102e95780634b56c0711461032c575b61016e610699565b005b34801561017c57600080fd5b5061016e6004803603606081101561019357600080fd5b506001600160a01b0381358116916020810135909116906040013561077b565b3480156101bf57600080fd5b50610286600480360360808110156101d657600080fd5b6001600160a01b0382358116926020810135909116916040820135919081019060808101606082013564010000000081111561021157600080fd5b82018360208201111561022357600080fd5b8035906020019184600183028401116401000000008311171561024557600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061084d945050505050565b604080516001600160e01b03199092168252519081900360200190f35b3480156102af57600080fd5b5061016e61085d565b3480156102c457600080fd5b506102cd61096e565b604080516001600160a01b039092168252519081900360200190f35b3480156102f557600080fd5b5061016e6004803603606081101561030c57600080fd5b506001600160a01b0381358116916020810135909116906040013561097d565b34801561033857600080fd5b5061016e6004803603602081101561034f57600080fd5b5035610d0e565b34801561036257600080fd5b506102cd610d54565b34801561037757600080fd5b5061016e610d63565b34801561038c57600080fd5b506102cd610dbe565b3480156103a157600080fd5b5061016e600480360360608110156103b857600080fd5b8101906020810181356401000000008111156103d357600080fd5b8201836020820111156103e557600080fd5b8035906020019184602083028401116401000000008311171561040757600080fd5b91939092909160208101903564010000000081111561042557600080fd5b82018360208201111561043757600080fd5b8035906020019184602083028401116401000000008311171561045957600080fd5b9193509150356001600160a01b0316610dcd565b34801561047957600080fd5b5061016e6004803603606081101561049057600080fd5b506001600160a01b03813581169160208101359091169060400135611037565b3480156104bc57600080fd5b506102cd6110a9565b3480156104d157600080fd5b506104da6110b8565b604080519115158252519081900360200190f35b3480156104fa57600080fd5b5061016e6004803603604081101561051157600080fd5b506001600160a01b0381351690602001356110c9565b34801561053357600080fd5b506102cd6110d4565b34801561054857600080fd5b5061016e6110e3565b34801561055d57600080fd5b5061057b6004803603602081101561057457600080fd5b50356110f5565b6040805192835260208301919091528051918290030190f35b3480156105a057600080fd5b506102cd61110e565b3480156105b557600080fd5b506104da61111d565b3480156105ca57600080fd5b5061016e600480360360408110156105e157600080fd5b506001600160a01b03813516906020013561112d565b34801561060357600080fd5b5061060c611138565b60408051918252519081900360200190f35b34801561062a57600080fd5b5061016e6004803603602081101561064157600080fd5b50356001600160a01b031661113e565b34801561065d57600080fd5b5061016e6004803603602081101561067457600080fd5b50356001600160a01b0316611171565b34801561069057600080fd5b5061016e61118e565b60035460408051638b9c948960e01b815290516000926001600160a01b031691638b9c9489916004808301926020929190829003018186803b1580156106de57600080fd5b505afa1580156106f2573d6000803e3d6000fd5b505050506040513d602081101561070857600080fd5b505160408051630d0e30db60e41b8152905191925082916001600160a01b0383169163d0e30db091349160048082019260009290919082900301818588803b15801561075357600080fd5b505af1158015610767573d6000803e3d6000fd5b505050505061077733833461119e565b5050565b600354604080516301f07db560e01b81526001600160a01b038681166004830152915191909216916301f07db5916024808301926020929190829003018186803b1580156107c857600080fd5b505afa1580156107dc573d6000803e3d6000fd5b505050506040513d60208110156107f257600080fd5b5051610832576040805162461bcd60e51b815260206004820152600a6024820152696e6f742065726337323160b01b604482015290519081900360640190fd5b61083d3384836112fc565b61084882848361119e565b505050565b630a85bd0160e11b949350505050565b60035460408051630c91702f60e31b8152815160009384936001600160a01b039091169263648b81789260048083019392829003018186803b1580156108a257600080fd5b505afa1580156108b6573d6000803e3d6000fd5b505050506040513d60408110156108cc57600080fd5b50805160209091015160055491935091506001600160a01b03808316911614158061090557506007546001600160a01b03838116911614155b6109405760405162461bcd60e51b815260040180806020018281038252603e8152602001806117ce603e913960400191505060405180910390fd5b600780546001600160a01b039384166001600160a01b03199182161790915560058054929093169116179055565b6007546001600160a01b031681565b600354604080516337b1d58560e01b815233600482015290516001600160a01b03909216916337b1d58591602480820192602092909190829003018186803b1580156109c857600080fd5b505afa1580156109dc573d6000803e3d6000fd5b505050506040513d60208110156109f257600080fd5b505160038111156109ff57fe5b60ff16610a4b576040805162461bcd60e51b81526020600482015260156024820152744e6f7420612076616c69642070726564696361746560581b604482015290519081900360640190fd5b60035460408051638b9c948960e01b815290516000926001600160a01b031691638b9c9489916004808301926020929190829003018186803b158015610a9057600080fd5b505afa158015610aa4573d6000803e3d6000fd5b505050506040513d6020811015610aba57600080fd5b5051600354604080516336a8279560e21b81526001600160a01b038881166004830152915193945091169163daa09e5491602480820192602092909190829003018186803b158015610b0b57600080fd5b505afa158015610b1f573d6000803e3d6000fd5b505050506040513d6020811015610b3557600080fd5b505115610bb157604080516323b872dd60e01b81523060048201526001600160a01b038581166024830152604482018590529151918616916323b872dd9160648082019260009290919082900301818387803b158015610b9457600080fd5b505af1158015610ba8573d6000803e3d6000fd5b50505050610d08565b806001600160a01b0316846001600160a01b03161415610c395760408051627b8a6760e11b8152600481018490526001600160a01b0385811660248301529151869283169162f714ce91604480830192600092919082900301818387803b158015610c1b57600080fd5b505af1158015610c2f573d6000803e3d6000fd5b5050505050610d08565b836001600160a01b031663a9059cbb84846040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015610c9957600080fd5b505af1158015610cad573d6000803e3d6000fd5b505050506040513d6020811015610cc357600080fd5b5051610d08576040805162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b604482015290519081900360640190fd5b50505050565b610d16611371565b80610d2057600080fd5b6008546040518291907f010c0265813c273963aa5e8683cf5c45a3b744ba6369c22af0958ec5fcf16b2090600090a3600855565b6002546001600160a01b031681565b610d6b6110b8565b610d7457600080fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6003546001600160a01b031681565b610dd56113ba565b838214610e19576040805162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a5908125b9c1d5d609a1b604482015290519081900360640190fd5b6004805460408051635391f48360e01b8152928301879052516000926001600160a01b0390921691635391f48391602480830192602092919082900301818787803b158015610e6757600080fd5b505af1158015610e7b573d6000803e3d6000fd5b505050506040513d6020811015610e9157600080fd5b50516003549091506001600160a01b031660005b8681101561102d57816001600160a01b03166301f07db5898984818110610ec857fe5b905060200201356001600160a01b03166040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610f1e57600080fd5b505afa158015610f32573d6000803e3d6000fd5b505050506040513d6020811015610f4857600080fd5b505115610f8c57610f8733898984818110610f5f57fe5b905060200201356001600160a01b0316888885818110610f7b57fe5b905060200201356112fc565b610fd9565b610fd93330888885818110610f9d57fe5b905060200201358b8b86818110610fb057fe5b905060200201356001600160a01b03166001600160a01b0316611402909392919063ffffffff16565b61101284898984818110610fe957fe5b905060200201356001600160a01b031688888581811061100557fe5b905060200201358661145c565b61102383600163ffffffff61162616565b9250600101610ea5565b5050505050505050565b60085481111561108e576040805162461bcd60e51b815260206004820152601d60248201527f657863656564206d6178696d756d206465706f73697420616d6f756e74000000604482015290519081900360640190fd5b61083d6001600160a01b03841633308463ffffffff61140216565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b610777823383611037565b6004546001600160a01b031681565b6110eb611371565b6110f361163f565b565b6006602052600090815260409020805460019091015482565b6005546001600160a01b031681565b600154600160a01b900460ff1681565b61077782338361077b565b60085481565b6111466110b8565b61114f57600080fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6111796110b8565b61118257600080fd5b61118b8161164e565b50565b611196611371565b6110f36116bc565b6111a66113ba565b60035460408051636416c18360e01b81526001600160a01b038086166004830152915185939290921691636416c18391602480820192602092909190829003018186803b1580156111f657600080fd5b505afa15801561120a573d6000803e3d6000fd5b505050506040513d602081101561122057600080fd5b5051611269576040805162461bcd60e51b81526020600482015260136024820152721513d2d15397d393d517d4d5541413d4951151606a1b604482015290519081900360640190fd5b610d08848484600460009054906101000a90046001600160a01b03166001600160a01b0316635391f48360016040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156112cb57600080fd5b505af11580156112df573d6000803e3d6000fd5b505050506040513d60208110156112f557600080fd5b505161145c565b60408051632142170760e11b81526001600160a01b038581166004830152306024830152604482018490529151918416916342842e0e9160648082019260009290919082900301818387803b15801561135457600080fd5b505af1158015611368573d6000803e3d6000fd5b50505050505050565b6002546001600160a01b031633146110f35760405162461bcd60e51b815260040180806020018281038252602681526020018061180c6026913960400191505060405180910390fd5b600154600160a01b900460ff16156110f3576040805162461bcd60e51b81526020600482015260066024820152651b1bd8dad95960d21b604482015290519081900360640190fd5b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052610d089085906116d1565b604080518082018252606086811b6bffffffffffffffffffffffff199081168284015286821b16607483015260888083018690528351808403909101815260a883018452805160209182012083524281840190815260008681526006835285812094518555905160019094019390935560055460075485516001600160a01b03808c1682860152808b168289015294810189905260808082018990528751808303909101815260a082018089526316f1983160e01b905291851660a4820181815260c48301988952835160e4840152835196909416976316f198319791969395909361010490930192908601918190849084905b83811015611568578181015183820152602001611550565b50505050905090810190601f1680156115955780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156115b557600080fd5b505af11580156115c9573d6000803e3d6000fd5b50505050826001600160a01b0316846001600160a01b03167f1dadc8d0683c6f9824e885935c1bec6f76816730dcec148dda8cf25a7b9f797b8484604051808381526020018281526020019250505060405180910390a350505050565b60008282018381101561163857600080fd5b9392505050565b6001805460ff60a01b19169055565b6001600160a01b03811661166157600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6001805460ff60a01b1916600160a01b179055565b6116e3826001600160a01b03166117c7565b6116ec57600080fd5b60006060836001600160a01b0316836040518082805190602001908083835b6020831061172a5780518252601f19909201916020918201910161170b565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461178c576040519150601f19603f3d011682016040523d82523d6000602084013e611791565b606091505b5091509150816117a057600080fd5b805115610d08578080602001905160208110156117bc57600080fd5b5051610d0857600080fd5b3b15159056fe41746c65617374206f6e65206f6620737461746553656e646572206f72206368696c64436861696e20616464726573732073686f756c64206368616e67654f6e6c7920676f7665726e616e636520636f6e747261637420697320617574686f72697a6564a265627a7a72315820b7ba4e5c5ee8a4a1915dfdf1d9929499a44c1cfff1f0a55c5119cdc6b39b506b64736f6c63430005110032
Deployed Bytecode Sourcemap
50002:5444:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50597:14;:12;:14::i;:::-;50002:5444;53650:324;;8:9:-1;5:2;;;30:1;27;20:12;5:2;53650:324:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;53650:324:0;;;;;;;;;;;;;;;;;:::i;1447:147::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1447:147:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;1447:147:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;1447:147:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;1447:147:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;1447:147:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;1447:147:0;;-1:-1:-1;1447:147:0;;-1:-1:-1;;;;;1447:147:0:i;:::-;;;;-1:-1:-1;;;;;;1447:147:0;;;;;;;;;;;;;;52868:425;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52868:425:0;;;:::i;49801:25::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;49801:25:0;;;:::i;:::-;;;;-1:-1:-1;;;;;49801:25:0;;;;;;;;;;;;;;50880:581;;8:9:-1;5:2;;;30:1;27;20:12;5:2;50880:581:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;50880:581:0;;;;;;;;;;;;;;;;;:::i;50627:245::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;50627:245:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;50627:245:0;;:::i;11133:29::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;11133:29:0;;;:::i;37494:140::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37494:140:0;;;:::i;49641:24::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;49641:24:0;;;:::i;51751:1002::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51751:1002:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;51751:1002:0;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;51751:1002:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;51751:1002:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;51751:1002:0;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;51751:1002:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;51751:1002:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;51751:1002:0;;-1:-1:-1;51751:1002:0;-1:-1:-1;51751:1002:0;-1:-1:-1;;;;;51751:1002:0;;:::i;53301:341::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;53301:341:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;53301:341:0;;;;;;;;;;;;;;;;;:::i;36704:79::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;36704:79:0;;;:::i;37039:92::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37039:92:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;51469:131;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51469:131:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;51469:131:0;;;;;;;;:::i;49672:26::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;49672:26:0;;;:::i;49017:73::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;49017:73:0;;;:::i;49744:48::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;49744:48:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;49744:48:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;49705:30;;8:9:-1;5:2;;;30:1;27;20:12;5:2;49705:30:0;;;:::i;48388:18::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48388:18:0;;;:::i;51608:135::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51608:135:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;51608:135:0;;;;;;;;:::i;49833:47::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;49833:47:0;;;:::i;:::-;;;;;;;;;;;;;;;;55152:114;;8:9:-1;5:2;;;30:1;27;20:12;5:2;55152:114:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;55152:114:0;-1:-1:-1;;;;;55152:114:0;;:::i;37811:109::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37811:109:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;37811:109:0;-1:-1:-1;;;;;37811:109:0;;:::i;48940:69::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48940:69:0;;;:::i;54023:250::-;54093:8;;:30;;;-1:-1:-1;;;54093:30:0;;;;54073:17;;-1:-1:-1;;;;;54093:8:0;;:28;;:30;;;;;;;;;;;;;;:8;:30;;;5:2:-1;;;;30:1;27;20:12;5:2;54093:30:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;54093:30:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;54093:30:0;54169:28;;;-1:-1:-1;;;54169:28:0;;;;54093:30;;-1:-1:-1;54093:30:0;;-1:-1:-1;;;;;54169:9:0;;;;;54185;;54169:28;;;;;54134:6;;54169:28;;;;;;;;54185:9;54169;:28;;;5:2:-1;;;;30:1;27;20:12;5:2;54169:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;54169:28:0;;;;;54208:57;54232:10;54244:9;54255;54208:23;:57::i;:::-;54023:250;;:::o;53650:324::-;53789:8;;:41;;;-1:-1:-1;;;53789:41:0;;-1:-1:-1;;;;;53789:41:0;;;;;;;;;:8;;;;;:33;;:41;;;;;;;;;;;;;;:8;:41;;;5:2:-1;;;;30:1;27;20:12;5:2;53789:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;53789:41:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;53789:41:0;53781:64;;;;;-1:-1:-1;;;53781:64:0;;;;;;;;;;;;-1:-1:-1;;;53781:64:0;;;;;;;;;;;;;;;53858:49;53878:10;53890:6;53898:8;53858:19;:49::i;:::-;53918:48;53942:5;53949:6;53957:8;53918:23;:48::i;:::-;53650:324;;;:::o;1447:147::-;-1:-1:-1;;;1447:147:0;;;;;;:::o;52868:425::-;52974:8;;:38;;;-1:-1:-1;;;52974:38:0;;;;52929:19;;;;-1:-1:-1;;;;;52974:8:0;;;;:36;;:38;;;;;;;;;;;:8;:38;;;5:2:-1;;;;30:1;27;20:12;5:2;52974:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;52974:38:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;52974:38:0;;;;;;;53069:11;;52974:38;;-1:-1:-1;52974:38:0;-1:-1:-1;;;;;;53045:36:0;;;53069:11;;53045:36;;;:65;;-1:-1:-1;53100:10:0;;-1:-1:-1;;;;;53085:25:0;;;53100:10;;53085:25;;53045:65;53023:177;;;;-1:-1:-1;;;53023:177:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53211:10;:24;;-1:-1:-1;;;;;53211:24:0;;;-1:-1:-1;;;;;;53211:24:0;;;;;;;53246:11;:39;;;;;;;;;;;52868:425::o;49801:25::-;;;-1:-1:-1;;;;;49801:25:0;;:::o;50880:581::-;50355:8;;:31;;;-1:-1:-1;;;50355:31:0;;50375:10;50355:31;;;;;;-1:-1:-1;;;;;50355:8:0;;;;:19;;:31;;;;;;;;;;;;;;;:8;:31;;;5:2:-1;;;;30:1;27;20:12;5:2;50355:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;50355:31:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;50355:31:0;50349:38;;;;;;;;:43;;50341:77;;;;;-1:-1:-1;;;50341:77:0;;;;;;;;;;;;-1:-1:-1;;;50341:77:0;;;;;;;;;;;;;;;51055:8;;:30;;;-1:-1:-1;;;51055:30:0;;;;51035:17;;-1:-1:-1;;;;;51055:8:0;;:28;;:30;;;;;;;;;;;;;;:8;:30;;;5:2:-1;;;;30:1;27;20:12;5:2;51055:30:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;51055:30:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;51055:30:0;51100:8;;:25;;;-1:-1:-1;;;51100:25:0;;-1:-1:-1;;;;;51100:25:0;;;;;;;;;51055:30;;-1:-1:-1;51100:8:0;;;:17;;:25;;;;;51055:30;;51100:25;;;;;;;;:8;:25;;;5:2:-1;;;;30:1;27;20:12;5:2;51100:25:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;51100:25:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;51100:25:0;51096:358;;;51142:66;;;-1:-1:-1;;;51142:66:0;;51179:4;51142:66;;;;-1:-1:-1;;;;;51142:66:0;;;;;;;;;;;;;;;:28;;;;;;:66;;;;;-1:-1:-1;;51142:66:0;;;;;;;;-1:-1:-1;51142:28:0;:66;;;5:2:-1;;;;30:1;27;20:12;5:2;51142:66:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;51142:66:0;;;;51096:358;;;51240:9;-1:-1:-1;;;;;51230:19:0;:6;-1:-1:-1;;;;;51230:19:0;;51226:228;;;51302:33;;;-1:-1:-1;;;51302:33:0;;;;;;;;-1:-1:-1;;;;;51302:33:0;;;;;;;;;51280:6;;51302:10;;;;;:33;;;;;51266:6;;51302:33;;;;;;;51266:6;51302:10;:33;;;5:2:-1;;;;30:1;27;20:12;5:2;51302:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;51302:33:0;;;;51226:228;;;;51383:6;-1:-1:-1;;;;;51376:23:0;;51400:5;51407:14;51376:46;;;;;;;;;;;;;-1:-1:-1;;;;;51376:46:0;-1:-1:-1;;;;;51376:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51376:46:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;51376:46:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;51376:46:0;51368:74;;;;;-1:-1:-1;;;51368:74:0;;;;;;;;;;;;-1:-1:-1;;;51368:74:0;;;;;;;;;;;;;;;50429:1;50880:581;;;:::o;50627:245::-;11312:19;:17;:19::i;:::-;50725:21;50717:30;;;;;;50785:15;;50763:56;;50802:16;;50785:15;50763:56;;;;;50830:15;:34;50627:245::o;11133:29::-;;;-1:-1:-1;;;;;11133:29:0;;:::o;37494:140::-;36916:9;:7;:9::i;:::-;36908:18;;;;;;37593:1;37577:6;;37556:40;;-1:-1:-1;;;;;37577:6:0;;;;37556:40;;37593:1;;37556:40;37624:1;37607:19;;-1:-1:-1;;;;;;37607:19:0;;;37494:140::o;49641:24::-;;;-1:-1:-1;;;;;49641:24:0;;:::o;51751:1002::-;48454:17;:15;:17::i;:::-;52039:40;;;52031:66;;;;;-1:-1:-1;;;52031:66:0;;;;;;;;;;;;-1:-1:-1;;;52031:66:0;;;;;;;;;;;;;;;52128:9;;;:41;;;-1:-1:-1;;;52128:41:0;;;;;;;;;52108:17;;-1:-1:-1;;;;;52128:9:0;;;;:25;;:41;;;;;;;;;;;;;;52108:17;52128:9;:41;;;5:2:-1;;;;30:1;27;20:12;5:2;52128:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;52128:41:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;52128:41:0;52201:8;;52128:41;;-1:-1:-1;;;;;;52201:8:0;52180:18;52222:524;52242:18;;;52222:524;;;52337:9;-1:-1:-1;;;;;52337:34:0;;52372:7;;52380:1;52372:10;;;;;;;;;;;;;-1:-1:-1;;;;;52372:10:0;52337:46;;;;;;;;;;;;;-1:-1:-1;;;;;52337:46:0;-1:-1:-1;;;;;52337:46:0;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52337:46:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;52337:46:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;52337:46:0;52333:273;;;52404:63;52424:10;52436:7;;52444:1;52436:10;;;;;;;;;;;;;-1:-1:-1;;;;;52436:10:0;52448:15;;52464:1;52448:18;;;;;;;;;;;;;52404:19;:63::i;:::-;52333:273;;;52508:82;52544:10;52564:4;52571:15;;52587:1;52571:18;;;;;;;;;;;;;52515:7;;52523:1;52515:10;;;;;;;;;;;;;-1:-1:-1;;;;;52515:10:0;-1:-1:-1;;;;;52508:35:0;;;:82;;;;;;:::i;:::-;52622:69;52642:5;52649:7;;52657:1;52649:10;;;;;;;;;;;;;-1:-1:-1;;;;;52649:10:0;52661:15;;52677:1;52661:18;;;;;;;;;;;;;52681:9;52622:19;:69::i;:::-;52718:16;:9;52732:1;52718:16;:13;:16;:::i;:::-;52706:28;-1:-1:-1;52262:3:0;;52222:524;;;;48482:1;;51751:1002;;;;;:::o;53301:341::-;53449:15;;53438:7;:26;;53430:68;;;;;-1:-1:-1;;;53430:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;53509:67;-1:-1:-1;;;;;53509:31:0;;53541:10;53561:4;53568:7;53509:67;:31;:67;:::i;36704:79::-;36742:7;36769:6;-1:-1:-1;;;;;36769:6:0;36704:79;:::o;37039:92::-;37079:4;37117:6;-1:-1:-1;;;;;37117:6:0;37103:10;:20;;37039:92::o;51469:131::-;51544:48;51564:6;51572:10;51584:7;51544:19;:48::i;49672:26::-;;;-1:-1:-1;;;;;49672:26:0;;:::o;49017:73::-;11312:19;:17;:19::i;:::-;49068:14;:12;:14::i;:::-;49017:73::o;49744:48::-;;;;;;;;;;;;;;;;;;;:::o;49705:30::-;;;-1:-1:-1;;;;;49705:30:0;;:::o;48388:18::-;;;-1:-1:-1;;;48388:18:0;;;;;:::o;51608:135::-;51685:50;51706:6;51714:10;51726:8;51685:20;:50::i;49833:47::-;;;;:::o;55152:114::-;36916:9;:7;:9::i;:::-;36908:18;;;;;;55225:9;:33;;-1:-1:-1;;;;;;55225:33:0;-1:-1:-1;;;;;55225:33:0;;;;;;;;;;55152:114::o;37811:109::-;36916:9;:7;:9::i;:::-;36908:18;;;;;;37884:28;37903:8;37884:18;:28::i;:::-;37811:109;:::o;48940:69::-;11312:19;:17;:19::i;:::-;48989:12;:10;:12::i;54281:357::-;48454:17;:15;:17::i;:::-;50215:8;;:30;;;-1:-1:-1;;;50215:30:0;;-1:-1:-1;;;;;50215:30:0;;;;;;;;;54443:6;;50215:8;;;;;:22;;:30;;;;;;;;;;;;;;;:8;:30;;;5:2:-1;;;;30:1;27;20:12;5:2;50215:30:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;50215:30:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;50215:30:0;50207:62;;;;;-1:-1:-1;;;50207:62:0;;;;;;;;;;;;-1:-1:-1;;;50207:62:0;;;;;;;;;;;;;;;54462:168;54496:5;54516:6;54537:14;54566:9;;;;;;;;;-1:-1:-1;;;;;54566:9:0;-1:-1:-1;;;;;54566:25:0;;54592:1;54566:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;54566:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;54566:28:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;54566:28:0;54462:19;:168::i;55274:169::-;55371:64;;;-1:-1:-1;;;55371:64:0;;-1:-1:-1;;;;;55371:64:0;;;;;;;55419:4;55371:64;;;;;;;;;;;;:32;;;;;;:64;;;;;-1:-1:-1;;55371:64:0;;;;;;;;-1:-1:-1;55371:32:0;:64;;;5:2:-1;;;;30:1;27;20:12;5:2;55371:64:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;55371:64:0;;;;55274:169;;;:::o;11359:182::-;11456:10;;-1:-1:-1;;;;;11456:10:0;11434;:33;11412:121;;;;-1:-1:-1;;;11412:121:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48499:85;48559:6;;-1:-1:-1;;;48559:6:0;;;;48558:7;48550:26;;;;;-1:-1:-1;;;48550:26:0;;;;;;;;;;;;-1:-1:-1;;;48550:26:0;;;;;;;;;;;;;;8274:204;8401:68;;;-1:-1:-1;;;;;8401:68:0;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;8401:68:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;8375:95:0;;8394:5;;8375:18;:95::i;54646:448::-;54836:77;;;;;;;;54859:47;;;;-1:-1:-1;;54859:47:0;;;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;54859:47:0;;;;;54849:58;;54859:47;54849:58;;;;54836:77;;54909:3;54836:77;;;;;;-1:-1:-1;54813:20:0;;;:8;:20;;;;;:100;;;;;;;;;;;;;;54924:11;;54946:10;;54958:53;;-1:-1:-1;;;;;54859:47:0;;;54958:53;;;;54859:47;;;54958:53;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;54958:53:0;;;;;;-1:-1:-1;;;54924:88:0;;54946:10;;;54924:88;;;;;;;;;;;;;;;;;;;;:11;;;;;:21;;54946:10;;54958:53;;54924:88;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;54924:88:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;54924:88:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;54924:88:0;;;;55051:6;-1:-1:-1;;;;;55028:58:0;55044:5;-1:-1:-1;;;;;55028:58:0;;55059:14;55075:10;55028:58;;;;;;;;;;;;;;;;;;;;;;;;54646:448;;;;:::o;5815:150::-;5873:7;5905:5;;;5929:6;;;;5921:15;;;;;;5956:1;5815:150;-1:-1:-1;;;5815:150:0:o;48655:58::-;48691:6;:14;;-1:-1:-1;;;;48691:14:0;;;48655:58::o;38070:187::-;-1:-1:-1;;;;;38144:22:0;;38136:31;;;;;;38204:6;;;38183:38;;-1:-1:-1;;;;;38183:38:0;;;;38204:6;;;38183:38;;;38232:6;:17;;-1:-1:-1;;;;;;38232:17:0;-1:-1:-1;;;;;38232:17:0;;;;;;;;;;38070:187::o;48592:55::-;48635:4;48626:13;;-1:-1:-1;;;;48626:13:0;-1:-1:-1;;;48626:13:0;;;48592:55::o;9947:887::-;10499:27;10507:5;-1:-1:-1;;;;;10499:25:0;;:27::i;:::-;10491:36;;;;;;10601:12;10615:23;10650:5;-1:-1:-1;;;;;10642:19:0;10662:4;10642:25;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;10642:25:0;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;10600:67:0;;;;10686:7;10678:16;;;;;;10711:17;;:21;10707:120;;10795:10;10784:30;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;10784:30:0;10776:39;;;;;6795:627;7367:20;7406:8;;;6795:627::o
Swarm Source
bzzr://b7ba4e5c5ee8a4a1915dfdf1d9929499a44c1cfff1f0a55c5119cdc6b39b506b
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.