Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00View 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
Optimization Enabled:
Yes with 200 runs
Other Settings:
istanbul EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity ^0.5.2;
import {ERC721Holder} from "openzeppelin-solidity/contracts/token/ERC721/ERC721Holder.sol";
import {IERC20} from "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
import {IERC721} from "openzeppelin-solidity/contracts/token/ERC721/IERC721.sol";
import {SafeMath} from "openzeppelin-solidity/contracts/math/SafeMath.sol";
import {SafeERC20} from "openzeppelin-solidity/contracts/token/ERC20/SafeERC20.sol";
import {Registry} from "../../common/Registry.sol";
import {WETH} from "../../common/tokens/WETH.sol";
import {IDepositManager} from "./IDepositManager.sol";
import {DepositManagerStorage} from "./DepositManagerStorage.sol";
import {StateSender} from "../stateSyncer/StateSender.sol";
import {GovernanceLockable} from "../../common/mixin/GovernanceLockable.sol";
import {RootChain} from "../RootChain.sol";
interface IPolygonMigration {
function migrate(uint256 amount) external;
}
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();
}
// new: governance function to migrate MATIC to POL
function migrateMatic() external onlyGovernance {
IERC20 matic = IERC20(registry.contractMap(keccak256("matic")));
_migrateMatic(matic.balanceOf(address(this)));
}
function _migrateMatic(uint256 _amount) private {
IERC20 matic = IERC20(registry.contractMap(keccak256("matic")));
address polygonMigration = registry.contractMap(keccak256("polygonMigration"));
// check that _amount is not too high
require(matic.balanceOf(address(this)) >= _amount, "amount exceeds this contract's MATIC balance");
// approve
matic.approve(polygonMigration, _amount);
// call migrate function
IPolygonMigration(polygonMigration).migrate(_amount);
}
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 {
// new: pay out POL when MATIC is withdrawn
if (_token == registry.contractMap(keccak256("matic"))) {
require(
IERC20(registry.contractMap(keccak256("pol"))).transfer(_user, _amountOrNFTId),
"TRANSFER_FAILED"
);
} 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 {
address matic = registry.contractMap(keccak256("matic"));
// new: auto-migrate MATIC to POL
if (_token == matic) {
_migrateMatic(_amountOrToken);
}
// new: bridge POL as MATIC, child chain behaviour does not change
else if (_token == registry.contractMap(keccak256("pol"))) {
_token = matic;
}
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);
}
}pragma solidity ^0.5.2;
import "./IERC721Receiver.sol";
contract ERC721Holder is IERC721Receiver {
function onERC721Received(address, address, uint256, bytes memory) public returns (bytes4) {
return this.onERC721Received.selector;
}
}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);
}pragma solidity ^0.5.2;
import "../../introspection/IERC165.sol";
/**
* @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;
}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;
}
}pragma solidity ^0.5.2;
import "./IERC20.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for 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)));
}
}
}pragma solidity ^0.5.2;
import {Governable} from "./governance/Governable.sol";
import {IWithdrawManager} from "../root/withdrawManager/IWithdrawManager.sol";
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];
}
}pragma solidity ^0.5.2;
import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
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;
}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;
}pragma solidity ^0.5.2;
import {Registry} from "../../common/Registry.sol";
import {RootChain} from "../RootChain.sol";
import {ProxyStorage} from "../../common/misc/ProxyStorage.sol";
import {StateSender} from "../stateSyncer/StateSender.sol";
import {GovernanceLockable} from "../../common/mixin/GovernanceLockable.sol";
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);
}pragma solidity ^0.5.2;
import {Ownable} from "openzeppelin-solidity/contracts/ownership/Ownable.sol";
import {SafeMath} from "openzeppelin-solidity/contracts/math/SafeMath.sol";
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);
}
}
}pragma solidity ^0.5.2;
import {Governable} from "../governance/Governable.sol";
import {Lockable} from "./Lockable.sol";
contract GovernanceLockable is Lockable, Governable {
constructor(address governance) public Governable(governance) {}
function lock() public onlyGovernance {
super.lock();
}
function unlock() public onlyGovernance {
super.unlock();
}
}pragma solidity ^0.5.2;
import {RLPReader} from "solidity-rlp/contracts/RLPReader.sol";
import {SafeMath} from "openzeppelin-solidity/contracts/math/SafeMath.sol";
import {RootChainHeader, RootChainStorage} from "./RootChainStorage.sol";
import {IStakeManager} from "../staking/stakeManager/IStakeManager.sol";
import {IRootChain} from "./IRootChain.sol";
import {Registry} from "../common/Registry.sol";
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));
}
}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);
}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);
}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;
}
}pragma solidity ^0.5.2;
import {IGovernance} from "./IGovernance.sol";
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"
);
}
}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;
}pragma solidity ^0.5.2;
import "./IERC20.sol";
import "../../math/SafeMath.sol";
/**
* @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));
}
}pragma solidity ^0.5.2;
import {Ownable} from "openzeppelin-solidity/contracts/ownership/Ownable.sol";
contract ProxyStorage is Ownable {
address internal proxyTo;
}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;
}
}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;
}
}// SPDX-License-Identifier: Apache-2.0 /* * @author Hamdi Allam [email protected] * Please reach out with any questions or concerns */ pragma solidity >=0.5.10 <0.9.0; library RLPReader { uint8 constant STRING_SHORT_START = 0x80; uint8 constant STRING_LONG_START = 0xb8; uint8 constant LIST_SHORT_START = 0xc0; uint8 constant LIST_LONG_START = 0xf8; uint8 constant WORD_SIZE = 32; struct RLPItem { uint256 len; uint256 memPtr; } struct Iterator { RLPItem item; // Item that's being iterated over. uint256 nextPtr; // Position of the next item in the list. } /* * @dev Returns the next element in the iteration. Reverts if it has not next element. * @param self The iterator. * @return The next element in the iteration. */ function next(Iterator memory self) internal pure returns (RLPItem memory) { require(hasNext(self)); uint256 ptr = self.nextPtr; uint256 itemLength = _itemLength(ptr); self.nextPtr = ptr + itemLength; return RLPItem(itemLength, ptr); } /* * @dev Returns true if the iteration has more elements. * @param self The iterator. * @return true if the iteration has more elements. */ function hasNext(Iterator memory self) internal pure returns (bool) { RLPItem memory item = self.item; return self.nextPtr < item.memPtr + item.len; } /* * @param item RLP encoded bytes */ function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) { uint256 memPtr; assembly { memPtr := add(item, 0x20) } return RLPItem(item.length, memPtr); } /* * @dev Create an iterator. Reverts if item is not a list. * @param self The RLP item. * @return An 'Iterator' over the item. */ function iterator(RLPItem memory self) internal pure returns (Iterator memory) { require(isList(self)); uint256 ptr = self.memPtr + _payloadOffset(self.memPtr); return Iterator(self, ptr); } /* * @param the RLP item. */ function rlpLen(RLPItem memory item) internal pure returns (uint256) { return item.len; } /* * @param the RLP item. * @return (memPtr, len) pair: location of the item's payload in memory. */ function payloadLocation(RLPItem memory item) internal pure returns (uint256, uint256) { uint256 offset = _payloadOffset(item.memPtr); uint256 memPtr = item.memPtr + offset; uint256 len = item.len - offset; // data length return (memPtr, len); } /* * @param the RLP item. */ function payloadLen(RLPItem memory item) internal pure returns (uint256) { (, uint256 len) = payloadLocation(item); return len; } /* * @param the RLP item containing the encoded list. */ function toList(RLPItem memory item) internal pure returns (RLPItem[] memory) { require(isList(item)); uint256 items = numItems(item); RLPItem[] memory result = new RLPItem[](items); uint256 memPtr = item.memPtr + _payloadOffset(item.memPtr); uint256 dataLen; for (uint256 i = 0; i < items; i++) { dataLen = _itemLength(memPtr); result[i] = RLPItem(dataLen, memPtr); memPtr = memPtr + dataLen; } return result; } // @return indicator whether encoded payload is a list. negate this function call for isData. function isList(RLPItem memory item) internal pure returns (bool) { if (item.len == 0) return false; uint8 byte0; uint256 memPtr = item.memPtr; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < LIST_SHORT_START) return false; return true; } /* * @dev A cheaper version of keccak256(toRlpBytes(item)) that avoids copying memory. * @return keccak256 hash of RLP encoded bytes. */ function rlpBytesKeccak256(RLPItem memory item) internal pure returns (bytes32) { uint256 ptr = item.memPtr; uint256 len = item.len; bytes32 result; assembly { result := keccak256(ptr, len) } return result; } /* * @dev A cheaper version of keccak256(toBytes(item)) that avoids copying memory. * @return keccak256 hash of the item payload. */ function payloadKeccak256(RLPItem memory item) internal pure returns (bytes32) { (uint256 memPtr, uint256 len) = payloadLocation(item); bytes32 result; assembly { result := keccak256(memPtr, len) } return result; } /** RLPItem conversions into data types **/ // @returns raw rlp encoding in bytes function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) { bytes memory result = new bytes(item.len); if (result.length == 0) return result; uint256 ptr; assembly { ptr := add(0x20, result) } copy(item.memPtr, ptr, item.len); return result; } // any non-zero byte except "0x80" is considered true function toBoolean(RLPItem memory item) internal pure returns (bool) { require(item.len == 1); uint256 result; uint256 memPtr = item.memPtr; assembly { result := byte(0, mload(memPtr)) } // SEE Github Issue #5. // Summary: Most commonly used RLP libraries (i.e Geth) will encode // "0" as "0x80" instead of as "0". We handle this edge case explicitly // here. if (result == 0 || result == STRING_SHORT_START) { return false; } else { return true; } } function toAddress(RLPItem memory item) internal pure returns (address) { // 1 byte for the length prefix require(item.len == 21); return address(uint160(toUint(item))); } function toUint(RLPItem memory item) internal pure returns (uint256) { require(item.len > 0 && item.len <= 33); (uint256 memPtr, uint256 len) = payloadLocation(item); uint256 result; assembly { result := mload(memPtr) // shift to the correct location if neccesary if lt(len, 32) { result := div(result, exp(256, sub(32, len))) } } return result; } // enforces 32 byte length function toUintStrict(RLPItem memory item) internal pure returns (uint256) { // one byte prefix require(item.len == 33); uint256 result; uint256 memPtr = item.memPtr + 1; assembly { result := mload(memPtr) } return result; } function toBytes(RLPItem memory item) internal pure returns (bytes memory) { require(item.len > 0); (uint256 memPtr, uint256 len) = payloadLocation(item); bytes memory result = new bytes(len); uint256 destPtr; assembly { destPtr := add(0x20, result) } copy(memPtr, destPtr, len); return result; } /* * Private Helpers */ // @return number of payload items inside an encoded list. function numItems(RLPItem memory item) private pure returns (uint256) { if (item.len == 0) return 0; uint256 count = 0; uint256 currPtr = item.memPtr + _payloadOffset(item.memPtr); uint256 endPtr = item.memPtr + item.len; while (currPtr < endPtr) { currPtr = currPtr + _itemLength(currPtr); // skip over an item count++; } return count; } // @return entire rlp item byte length function _itemLength(uint256 memPtr) private pure returns (uint256) { uint256 itemLen; uint256 byte0; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < STRING_SHORT_START) { itemLen = 1; } else if (byte0 < STRING_LONG_START) { itemLen = byte0 - STRING_SHORT_START + 1; } else if (byte0 < LIST_SHORT_START) { assembly { let byteLen := sub(byte0, 0xb7) // # of bytes the actual length is memPtr := add(memPtr, 1) // skip over the first byte /* 32 byte word size */ let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len itemLen := add(dataLen, add(byteLen, 1)) } } else if (byte0 < LIST_LONG_START) { itemLen = byte0 - LIST_SHORT_START + 1; } else { assembly { let byteLen := sub(byte0, 0xf7) memPtr := add(memPtr, 1) let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length itemLen := add(dataLen, add(byteLen, 1)) } } return itemLen; } // @return number of bytes until the data function _payloadOffset(uint256 memPtr) private pure returns (uint256) { uint256 byte0; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < STRING_SHORT_START) { return 0; } else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START)) { return 1; } else if (byte0 < LIST_SHORT_START) { // being explicit return byte0 - (STRING_LONG_START - 1) + 1; } else { return byte0 - (LIST_LONG_START - 1) + 1; } } /* * @param src Pointer to source * @param dest Pointer to destination * @param len Amount of memory to copy from the source */ function copy(uint256 src, uint256 dest, uint256 len) private pure { if (len == 0) return; // copy as many word sizes as possible for (; len >= WORD_SIZE; len -= WORD_SIZE) { assembly { mstore(dest, mload(src)) } src += WORD_SIZE; dest += WORD_SIZE; } if (len > 0) { // left over bytes. Mask is used to remove unwanted bytes from the word uint256 mask = 256**(WORD_SIZE - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) // zero out src let destpart := and(mload(dest), mask) // retrieve the bytes mstore(dest, or(destpart, srcpart)) } } } }
pragma solidity ^0.5.2;
import {Registry} from "../common/Registry.sol";
import {ProxyStorage} from "../common/misc/ProxyStorage.sol";
import {ChainIdMixin} from "../common/mixin/ChainIdMixin.sol";
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;
}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 transferFundsPOL(
uint256 validatorId,
uint256 amount,
address delegator
) external returns (bool);
function delegationDeposit(
uint256 validatorId,
uint256 amount,
address delegator
) external returns (bool);
function delegationDepositPOL(
uint256 validatorId,
uint256 amount,
address delegator
) external returns (bool);
function unstake(uint256 validatorId) external;
function unstakePOL(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 stakeForPOL(
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;
}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);
}pragma solidity ^0.5.2;
interface IGovernance {
function update(address target, bytes calldata data) external;
}pragma solidity ^0.5.2;
contract ChainIdMixin {
bytes constant public networkId = hex"3A99";
uint256 constant public CHAINID = 15001;
}{
"remappings": [
"openzeppelin-solidity/=node_modules/openzeppelin-solidity/",
"solidity-rlp/=node_modules/solidity-rlp/",
"@ensdomains/=node_modules/@ensdomains/",
"eth-gas-reporter/=node_modules/eth-gas-reporter/",
"forge-std/=lib/forge-std/src/",
"hardhat/=node_modules/hardhat/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "istanbul",
"libraries": {}
}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":[],"name":"migrateMatic","outputs":[],"payable":false,"stateMutability":"nonpayable","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
608060405268056bc75e2d6310000060085534801561001d57600080fd5b50600080546001600160a01b031916331780825560405182916001600160a01b03169082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3600280546001600160a01b0319166001600160a01b039290921691909117905550611fc5806100976000396000f3fe6080604052600436106101815760003560e01c80638f32d59b116100d1578063cb10f94c1161008a578063e7af7ba111610064578063e7af7ba114610627578063f22037111461064e578063f2fde38b14610681578063f83d08ba146106b457610181565b8063cb10f94c146105c4578063cf309012146105d9578063d29a4bf6146105ee57610181565b80638f32d59b146104f557806397feb9261461051e578063987ab9db1461055757806398ea5fca14610181578063a69df4b51461056c578063b02c43d01461058157610181565b80635aa6e6751161013e5780637b1f7117116101185780637b1f7117146103b0578063889a0538146104885780638b9e4f931461049d5780638da5cb5b146104e057610181565b80635aa6e67514610371578063715018a6146103865780637b1039991461039b57610181565b8063072b15351461018b578063150b7a02146101ce57806342be8379146102be57806342fc47fb146102d357806349f4cc17146103045780634b56c07114610347575b6101896106c9565b005b34801561019757600080fd5b50610189600480360360608110156101ae57600080fd5b506001600160a01b038135811691602081013590911690604001356107ab565b3480156101da57600080fd5b506102a1600480360360808110156101f157600080fd5b6001600160a01b0382358116926020810135909116916040820135919081019060808101606082013564010000000081111561022c57600080fd5b82018360208201111561023e57600080fd5b8035906020019184600183028401116401000000008311171561026057600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061087d945050505050565b604080516001600160e01b03199092168252519081900360200190f35b3480156102ca57600080fd5b5061018961088d565b3480156102df57600080fd5b506102e861099e565b604080516001600160a01b039092168252519081900360200190f35b34801561031057600080fd5b506101896004803603606081101561032757600080fd5b506001600160a01b038135811691602081013590911690604001356109ad565b34801561035357600080fd5b506101896004803603602081101561036a57600080fd5b5035610f2d565b34801561037d57600080fd5b506102e8610f73565b34801561039257600080fd5b50610189610f82565b3480156103a757600080fd5b506102e8610fdd565b3480156103bc57600080fd5b50610189600480360360608110156103d357600080fd5b8101906020810181356401000000008111156103ee57600080fd5b82018360208201111561040057600080fd5b8035906020019184602083028401116401000000008311171561042257600080fd5b91939092909160208101903564010000000081111561044057600080fd5b82018360208201111561045257600080fd5b8035906020019184602083028401116401000000008311171561047457600080fd5b9193509150356001600160a01b0316610fec565b34801561049457600080fd5b50610189611256565b3480156104a957600080fd5b50610189600480360360608110156104c057600080fd5b506001600160a01b0381358116916020810135909116906040013561136b565b3480156104ec57600080fd5b506102e86113dd565b34801561050157600080fd5b5061050a6113ec565b604080519115158252519081900360200190f35b34801561052a57600080fd5b506101896004803603604081101561054157600080fd5b506001600160a01b0381351690602001356113fd565b34801561056357600080fd5b506102e8611408565b34801561057857600080fd5b50610189611417565b34801561058d57600080fd5b506105ab600480360360208110156105a457600080fd5b5035611429565b6040805192835260208301919091528051918290030190f35b3480156105d057600080fd5b506102e8611442565b3480156105e557600080fd5b5061050a611451565b3480156105fa57600080fd5b506101896004803603604081101561061157600080fd5b506001600160a01b038135169060200135611461565b34801561063357600080fd5b5061063c61146c565b60408051918252519081900360200190f35b34801561065a57600080fd5b506101896004803603602081101561067157600080fd5b50356001600160a01b0316611472565b34801561068d57600080fd5b50610189600480360360208110156106a457600080fd5b50356001600160a01b03166114a5565b3480156106c057600080fd5b506101896114bf565b60035460408051638b9c948960e01b815290516000926001600160a01b031691638b9c9489916004808301926020929190829003018186803b15801561070e57600080fd5b505afa158015610722573d6000803e3d6000fd5b505050506040513d602081101561073857600080fd5b505160408051630d0e30db60e41b8152905191925082916001600160a01b0383169163d0e30db091349160048082019260009290919082900301818588803b15801561078357600080fd5b505af1158015610797573d6000803e3d6000fd5b50505050506107a73383346114cf565b5050565b600354604080516301f07db560e01b81526001600160a01b038681166004830152915191909216916301f07db5916024808301926020929190829003018186803b1580156107f857600080fd5b505afa15801561080c573d6000803e3d6000fd5b505050506040513d602081101561082257600080fd5b5051610862576040805162461bcd60e51b815260206004820152600a6024820152696e6f742065726337323160b01b604482015290519081900360640190fd5b61086d33848361162d565b6108788284836114cf565b505050565b630a85bd0160e11b949350505050565b60035460408051630c91702f60e31b8152815160009384936001600160a01b039091169263648b81789260048083019392829003018186803b1580156108d257600080fd5b505afa1580156108e6573d6000803e3d6000fd5b505050506040513d60408110156108fc57600080fd5b50805160209091015160055491935091506001600160a01b03808316911614158061093557506007546001600160a01b03838116911614155b6109705760405162461bcd60e51b815260040180806020018281038252603e815260200180611f2d603e913960400191505060405180910390fd5b600780546001600160a01b039384166001600160a01b03199182161790915560058054929093169116179055565b6007546001600160a01b031681565b600354604080516337b1d58560e01b815233600482015290516001600160a01b03909216916337b1d58591602480820192602092909190829003018186803b1580156109f857600080fd5b505afa158015610a0c573d6000803e3d6000fd5b505050506040513d6020811015610a2257600080fd5b50516003811115610a2f57fe5b60ff16610a7b576040805162461bcd60e51b81526020600482015260156024820152744e6f7420612076616c69642070726564696361746560581b604482015290519081900360640190fd5b60035460408051638b9c948960e01b815290516000926001600160a01b031691638b9c9489916004808301926020929190829003018186803b158015610ac057600080fd5b505afa158015610ad4573d6000803e3d6000fd5b505050506040513d6020811015610aea57600080fd5b5051600354604080516336a8279560e21b81526001600160a01b038881166004830152915193945091169163daa09e5491602480820192602092909190829003018186803b158015610b3b57600080fd5b505afa158015610b4f573d6000803e3d6000fd5b505050506040513d6020811015610b6557600080fd5b505115610be157604080516323b872dd60e01b81523060048201526001600160a01b038581166024830152604482018590529151918616916323b872dd9160648082019260009290919082900301818387803b158015610bc457600080fd5b505af1158015610bd8573d6000803e3d6000fd5b50505050610f27565b806001600160a01b0316846001600160a01b03161415610c695760408051627b8a6760e11b8152600481018490526001600160a01b0385811660248301529151869283169162f714ce91604480830192600092919082900301818387803b158015610c4b57600080fd5b505af1158015610c5f573d6000803e3d6000fd5b5050505050610f27565b60035460408051646d6174696360d81b8152815190819003600501812063cac39a0560e01b8252600482015290516001600160a01b039092169163cac39a0591602480820192602092909190829003018186803b158015610cc957600080fd5b505afa158015610cdd573d6000803e3d6000fd5b505050506040513d6020811015610cf357600080fd5b50516001600160a01b0385811691161415610e58576003805460408051621c1bdb60ea1b8152815190819003909301832063cac39a0560e01b84526004840152516001600160a01b039091169163cac39a05916024808301926020929190829003018186803b158015610d6557600080fd5b505afa158015610d79573d6000803e3d6000fd5b505050506040513d6020811015610d8f57600080fd5b50516040805163a9059cbb60e01b81526001600160a01b038681166004830152602482018690529151919092169163a9059cbb9160448083019260209291908290030181600087803b158015610de457600080fd5b505af1158015610df8573d6000803e3d6000fd5b505050506040513d6020811015610e0e57600080fd5b5051610e53576040805162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b604482015290519081900360640190fd5b610f27565b836001600160a01b031663a9059cbb84846040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015610eb857600080fd5b505af1158015610ecc573d6000803e3d6000fd5b505050506040513d6020811015610ee257600080fd5b5051610f27576040805162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b604482015290519081900360640190fd5b50505050565b610f356116a2565b80610f3f57600080fd5b6008546040518291907f010c0265813c273963aa5e8683cf5c45a3b744ba6369c22af0958ec5fcf16b2090600090a3600855565b6002546001600160a01b031681565b610f8a6113ec565b610f9357600080fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6003546001600160a01b031681565b610ff46116eb565b838214611038576040805162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a5908125b9c1d5d609a1b604482015290519081900360640190fd5b6004805460408051635391f48360e01b8152928301879052516000926001600160a01b0390921691635391f48391602480830192602092919082900301818787803b15801561108657600080fd5b505af115801561109a573d6000803e3d6000fd5b505050506040513d60208110156110b057600080fd5b50516003549091506001600160a01b031660005b8681101561124c57816001600160a01b03166301f07db58989848181106110e757fe5b905060200201356001600160a01b03166040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561113d57600080fd5b505afa158015611151573d6000803e3d6000fd5b505050506040513d602081101561116757600080fd5b5051156111ab576111a63389898481811061117e57fe5b905060200201356001600160a01b031688888581811061119a57fe5b9050602002013561162d565b6111f8565b6111f833308888858181106111bc57fe5b905060200201358b8b868181106111cf57fe5b905060200201356001600160a01b03166001600160a01b0316611733909392919063ffffffff16565b6112318489898481811061120857fe5b905060200201356001600160a01b031688888581811061122457fe5b905060200201358661178d565b61124283600163ffffffff611aa816565b92506001016110c4565b5050505050505050565b61125e6116a2565b60035460408051646d6174696360d81b8152815190819003600501812063cac39a0560e01b8252600482015290516000926001600160a01b03169163cac39a05916024808301926020929190829003018186803b1580156112be57600080fd5b505afa1580156112d2573d6000803e3d6000fd5b505050506040513d60208110156112e857600080fd5b5051604080516370a0823160e01b81523060048201529051919250611368916001600160a01b038416916370a08231916024808301926020929190829003018186803b15801561133757600080fd5b505afa15801561134b573d6000803e3d6000fd5b505050506040513d602081101561136157600080fd5b5051611ac1565b50565b6008548111156113c2576040805162461bcd60e51b815260206004820152601d60248201527f657863656564206d6178696d756d206465706f73697420616d6f756e74000000604482015290519081900360640190fd5b61086d6001600160a01b03841633308463ffffffff61173316565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b6107a782338361136b565b6004546001600160a01b031681565b61141f6116a2565b611427611d72565b565b6006602052600090815260409020805460019091015482565b6005546001600160a01b031681565b600154600160a01b900460ff1681565b6107a78233836107ab565b60085481565b61147a6113ec565b61148357600080fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6114ad6113ec565b6114b657600080fd5b61136881611d81565b6114c76116a2565b611427611def565b6114d76116eb565b60035460408051636416c18360e01b81526001600160a01b038086166004830152915185939290921691636416c18391602480820192602092909190829003018186803b15801561152757600080fd5b505afa15801561153b573d6000803e3d6000fd5b505050506040513d602081101561155157600080fd5b505161159a576040805162461bcd60e51b81526020600482015260136024820152721513d2d15397d393d517d4d5541413d4951151606a1b604482015290519081900360640190fd5b610f27848484600460009054906101000a90046001600160a01b03166001600160a01b0316635391f48360016040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156115fc57600080fd5b505af1158015611610573d6000803e3d6000fd5b505050506040513d602081101561162657600080fd5b505161178d565b60408051632142170760e11b81526001600160a01b038581166004830152306024830152604482018490529151918416916342842e0e9160648082019260009290919082900301818387803b15801561168557600080fd5b505af1158015611699573d6000803e3d6000fd5b50505050505050565b6002546001600160a01b031633146114275760405162461bcd60e51b8152600401808060200182810382526026815260200180611f6b6026913960400191505060405180910390fd5b600154600160a01b900460ff1615611427576040805162461bcd60e51b81526020600482015260066024820152651b1bd8dad95960d21b604482015290519081900360640190fd5b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052610f27908590611e04565b60035460408051646d6174696360d81b8152815190819003600501812063cac39a0560e01b8252600482015290516000926001600160a01b03169163cac39a05916024808301926020929190829003018186803b1580156117ed57600080fd5b505afa158015611801573d6000803e3d6000fd5b505050506040513d602081101561181757600080fd5b505190506001600160a01b03848116908216141561183d5761183883611ac1565b6118dd565b6003805460408051621c1bdb60ea1b8152815190819003909301832063cac39a0560e01b84526004840152516001600160a01b039091169163cac39a05916024808301926020929190829003018186803b15801561189a57600080fd5b505afa1580156118ae573d6000803e3d6000fd5b505050506040513d60208110156118c457600080fd5b50516001600160a01b03858116911614156118dd578093505b604080518082018252606087811b6bffffffffffffffffffffffff199081168284015287821b16607483015260888083018790528351808403909101815260a883018452805160209182012083524281840190815260008781526006835285812094518555905160019094019390935560055460075485516001600160a01b03808d1682860152808c16828901529481018a905260808082018a90528751808303909101815260a082018089526316f1983160e01b905291851660a4820181815260c48301988952835160e4840152835196909416976316f198319791969395909361010490930192908601918190849084905b838110156119e95781810151838201526020016119d1565b50505050905090810190601f168015611a165780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015611a3657600080fd5b505af1158015611a4a573d6000803e3d6000fd5b50505050836001600160a01b0316856001600160a01b03167f1dadc8d0683c6f9824e885935c1bec6f76816730dcec148dda8cf25a7b9f797b8585604051808381526020018281526020019250505060405180910390a35050505050565b600082820183811015611aba57600080fd5b9392505050565b60035460408051646d6174696360d81b8152815190819003600501812063cac39a0560e01b8252600482015290516000926001600160a01b03169163cac39a05916024808301926020929190829003018186803b158015611b2157600080fd5b505afa158015611b35573d6000803e3d6000fd5b505050506040513d6020811015611b4b57600080fd5b5051600354604080516f3837b63cb3b7b726b4b3b930ba34b7b760811b8152815190819003601001812063cac39a0560e01b8252600482015290519293506000926001600160a01b039092169163cac39a0591602480820192602092909190829003018186803b158015611bbe57600080fd5b505afa158015611bd2573d6000803e3d6000fd5b505050506040513d6020811015611be857600080fd5b5051604080516370a0823160e01b8152306004820152905191925084916001600160a01b038516916370a08231916024808301926020929190829003018186803b158015611c3557600080fd5b505afa158015611c49573d6000803e3d6000fd5b505050506040513d6020811015611c5f57600080fd5b50511015611c9e5760405162461bcd60e51b815260040180806020018281038252602c815260200180611f01602c913960400191505060405180910390fd5b816001600160a01b031663095ea7b382856040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015611cfe57600080fd5b505af1158015611d12573d6000803e3d6000fd5b505050506040513d6020811015611d2857600080fd5b5050604080516308a960c160e31b81526004810185905290516001600160a01b0383169163454b060891602480830192600092919082900301818387803b15801561168557600080fd5b6001805460ff60a01b19169055565b6001600160a01b038116611d9457600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6001805460ff60a01b1916600160a01b179055565b611e16826001600160a01b0316611efa565b611e1f57600080fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310611e5d5780518252601f199092019160209182019101611e3e565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611ebf576040519150601f19603f3d011682016040523d82523d6000602084013e611ec4565b606091505b509150915081611ed357600080fd5b805115610f2757808060200190516020811015611eef57600080fd5b5051610f2757600080fd5b3b15159056fe616d6f756e742065786365656473207468697320636f6e74726163742773204d415449432062616c616e636541746c65617374206f6e65206f6620737461746553656e646572206f72206368696c64436861696e20616464726573732073686f756c64206368616e67654f6e6c7920676f7665726e616e636520636f6e747261637420697320617574686f72697a6564a265627a7a72315820c1dbd9f6fea99031eca29e23c9ebb67c5314bf5383a338b9419970be48a5842664736f6c63430005110032
Deployed Bytecode
0x6080604052600436106101815760003560e01c80638f32d59b116100d1578063cb10f94c1161008a578063e7af7ba111610064578063e7af7ba114610627578063f22037111461064e578063f2fde38b14610681578063f83d08ba146106b457610181565b8063cb10f94c146105c4578063cf309012146105d9578063d29a4bf6146105ee57610181565b80638f32d59b146104f557806397feb9261461051e578063987ab9db1461055757806398ea5fca14610181578063a69df4b51461056c578063b02c43d01461058157610181565b80635aa6e6751161013e5780637b1f7117116101185780637b1f7117146103b0578063889a0538146104885780638b9e4f931461049d5780638da5cb5b146104e057610181565b80635aa6e67514610371578063715018a6146103865780637b1039991461039b57610181565b8063072b15351461018b578063150b7a02146101ce57806342be8379146102be57806342fc47fb146102d357806349f4cc17146103045780634b56c07114610347575b6101896106c9565b005b34801561019757600080fd5b50610189600480360360608110156101ae57600080fd5b506001600160a01b038135811691602081013590911690604001356107ab565b3480156101da57600080fd5b506102a1600480360360808110156101f157600080fd5b6001600160a01b0382358116926020810135909116916040820135919081019060808101606082013564010000000081111561022c57600080fd5b82018360208201111561023e57600080fd5b8035906020019184600183028401116401000000008311171561026057600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061087d945050505050565b604080516001600160e01b03199092168252519081900360200190f35b3480156102ca57600080fd5b5061018961088d565b3480156102df57600080fd5b506102e861099e565b604080516001600160a01b039092168252519081900360200190f35b34801561031057600080fd5b506101896004803603606081101561032757600080fd5b506001600160a01b038135811691602081013590911690604001356109ad565b34801561035357600080fd5b506101896004803603602081101561036a57600080fd5b5035610f2d565b34801561037d57600080fd5b506102e8610f73565b34801561039257600080fd5b50610189610f82565b3480156103a757600080fd5b506102e8610fdd565b3480156103bc57600080fd5b50610189600480360360608110156103d357600080fd5b8101906020810181356401000000008111156103ee57600080fd5b82018360208201111561040057600080fd5b8035906020019184602083028401116401000000008311171561042257600080fd5b91939092909160208101903564010000000081111561044057600080fd5b82018360208201111561045257600080fd5b8035906020019184602083028401116401000000008311171561047457600080fd5b9193509150356001600160a01b0316610fec565b34801561049457600080fd5b50610189611256565b3480156104a957600080fd5b50610189600480360360608110156104c057600080fd5b506001600160a01b0381358116916020810135909116906040013561136b565b3480156104ec57600080fd5b506102e86113dd565b34801561050157600080fd5b5061050a6113ec565b604080519115158252519081900360200190f35b34801561052a57600080fd5b506101896004803603604081101561054157600080fd5b506001600160a01b0381351690602001356113fd565b34801561056357600080fd5b506102e8611408565b34801561057857600080fd5b50610189611417565b34801561058d57600080fd5b506105ab600480360360208110156105a457600080fd5b5035611429565b6040805192835260208301919091528051918290030190f35b3480156105d057600080fd5b506102e8611442565b3480156105e557600080fd5b5061050a611451565b3480156105fa57600080fd5b506101896004803603604081101561061157600080fd5b506001600160a01b038135169060200135611461565b34801561063357600080fd5b5061063c61146c565b60408051918252519081900360200190f35b34801561065a57600080fd5b506101896004803603602081101561067157600080fd5b50356001600160a01b0316611472565b34801561068d57600080fd5b50610189600480360360208110156106a457600080fd5b50356001600160a01b03166114a5565b3480156106c057600080fd5b506101896114bf565b60035460408051638b9c948960e01b815290516000926001600160a01b031691638b9c9489916004808301926020929190829003018186803b15801561070e57600080fd5b505afa158015610722573d6000803e3d6000fd5b505050506040513d602081101561073857600080fd5b505160408051630d0e30db60e41b8152905191925082916001600160a01b0383169163d0e30db091349160048082019260009290919082900301818588803b15801561078357600080fd5b505af1158015610797573d6000803e3d6000fd5b50505050506107a73383346114cf565b5050565b600354604080516301f07db560e01b81526001600160a01b038681166004830152915191909216916301f07db5916024808301926020929190829003018186803b1580156107f857600080fd5b505afa15801561080c573d6000803e3d6000fd5b505050506040513d602081101561082257600080fd5b5051610862576040805162461bcd60e51b815260206004820152600a6024820152696e6f742065726337323160b01b604482015290519081900360640190fd5b61086d33848361162d565b6108788284836114cf565b505050565b630a85bd0160e11b949350505050565b60035460408051630c91702f60e31b8152815160009384936001600160a01b039091169263648b81789260048083019392829003018186803b1580156108d257600080fd5b505afa1580156108e6573d6000803e3d6000fd5b505050506040513d60408110156108fc57600080fd5b50805160209091015160055491935091506001600160a01b03808316911614158061093557506007546001600160a01b03838116911614155b6109705760405162461bcd60e51b815260040180806020018281038252603e815260200180611f2d603e913960400191505060405180910390fd5b600780546001600160a01b039384166001600160a01b03199182161790915560058054929093169116179055565b6007546001600160a01b031681565b600354604080516337b1d58560e01b815233600482015290516001600160a01b03909216916337b1d58591602480820192602092909190829003018186803b1580156109f857600080fd5b505afa158015610a0c573d6000803e3d6000fd5b505050506040513d6020811015610a2257600080fd5b50516003811115610a2f57fe5b60ff16610a7b576040805162461bcd60e51b81526020600482015260156024820152744e6f7420612076616c69642070726564696361746560581b604482015290519081900360640190fd5b60035460408051638b9c948960e01b815290516000926001600160a01b031691638b9c9489916004808301926020929190829003018186803b158015610ac057600080fd5b505afa158015610ad4573d6000803e3d6000fd5b505050506040513d6020811015610aea57600080fd5b5051600354604080516336a8279560e21b81526001600160a01b038881166004830152915193945091169163daa09e5491602480820192602092909190829003018186803b158015610b3b57600080fd5b505afa158015610b4f573d6000803e3d6000fd5b505050506040513d6020811015610b6557600080fd5b505115610be157604080516323b872dd60e01b81523060048201526001600160a01b038581166024830152604482018590529151918616916323b872dd9160648082019260009290919082900301818387803b158015610bc457600080fd5b505af1158015610bd8573d6000803e3d6000fd5b50505050610f27565b806001600160a01b0316846001600160a01b03161415610c695760408051627b8a6760e11b8152600481018490526001600160a01b0385811660248301529151869283169162f714ce91604480830192600092919082900301818387803b158015610c4b57600080fd5b505af1158015610c5f573d6000803e3d6000fd5b5050505050610f27565b60035460408051646d6174696360d81b8152815190819003600501812063cac39a0560e01b8252600482015290516001600160a01b039092169163cac39a0591602480820192602092909190829003018186803b158015610cc957600080fd5b505afa158015610cdd573d6000803e3d6000fd5b505050506040513d6020811015610cf357600080fd5b50516001600160a01b0385811691161415610e58576003805460408051621c1bdb60ea1b8152815190819003909301832063cac39a0560e01b84526004840152516001600160a01b039091169163cac39a05916024808301926020929190829003018186803b158015610d6557600080fd5b505afa158015610d79573d6000803e3d6000fd5b505050506040513d6020811015610d8f57600080fd5b50516040805163a9059cbb60e01b81526001600160a01b038681166004830152602482018690529151919092169163a9059cbb9160448083019260209291908290030181600087803b158015610de457600080fd5b505af1158015610df8573d6000803e3d6000fd5b505050506040513d6020811015610e0e57600080fd5b5051610e53576040805162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b604482015290519081900360640190fd5b610f27565b836001600160a01b031663a9059cbb84846040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015610eb857600080fd5b505af1158015610ecc573d6000803e3d6000fd5b505050506040513d6020811015610ee257600080fd5b5051610f27576040805162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b604482015290519081900360640190fd5b50505050565b610f356116a2565b80610f3f57600080fd5b6008546040518291907f010c0265813c273963aa5e8683cf5c45a3b744ba6369c22af0958ec5fcf16b2090600090a3600855565b6002546001600160a01b031681565b610f8a6113ec565b610f9357600080fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6003546001600160a01b031681565b610ff46116eb565b838214611038576040805162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a5908125b9c1d5d609a1b604482015290519081900360640190fd5b6004805460408051635391f48360e01b8152928301879052516000926001600160a01b0390921691635391f48391602480830192602092919082900301818787803b15801561108657600080fd5b505af115801561109a573d6000803e3d6000fd5b505050506040513d60208110156110b057600080fd5b50516003549091506001600160a01b031660005b8681101561124c57816001600160a01b03166301f07db58989848181106110e757fe5b905060200201356001600160a01b03166040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561113d57600080fd5b505afa158015611151573d6000803e3d6000fd5b505050506040513d602081101561116757600080fd5b5051156111ab576111a63389898481811061117e57fe5b905060200201356001600160a01b031688888581811061119a57fe5b9050602002013561162d565b6111f8565b6111f833308888858181106111bc57fe5b905060200201358b8b868181106111cf57fe5b905060200201356001600160a01b03166001600160a01b0316611733909392919063ffffffff16565b6112318489898481811061120857fe5b905060200201356001600160a01b031688888581811061122457fe5b905060200201358661178d565b61124283600163ffffffff611aa816565b92506001016110c4565b5050505050505050565b61125e6116a2565b60035460408051646d6174696360d81b8152815190819003600501812063cac39a0560e01b8252600482015290516000926001600160a01b03169163cac39a05916024808301926020929190829003018186803b1580156112be57600080fd5b505afa1580156112d2573d6000803e3d6000fd5b505050506040513d60208110156112e857600080fd5b5051604080516370a0823160e01b81523060048201529051919250611368916001600160a01b038416916370a08231916024808301926020929190829003018186803b15801561133757600080fd5b505afa15801561134b573d6000803e3d6000fd5b505050506040513d602081101561136157600080fd5b5051611ac1565b50565b6008548111156113c2576040805162461bcd60e51b815260206004820152601d60248201527f657863656564206d6178696d756d206465706f73697420616d6f756e74000000604482015290519081900360640190fd5b61086d6001600160a01b03841633308463ffffffff61173316565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b6107a782338361136b565b6004546001600160a01b031681565b61141f6116a2565b611427611d72565b565b6006602052600090815260409020805460019091015482565b6005546001600160a01b031681565b600154600160a01b900460ff1681565b6107a78233836107ab565b60085481565b61147a6113ec565b61148357600080fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6114ad6113ec565b6114b657600080fd5b61136881611d81565b6114c76116a2565b611427611def565b6114d76116eb565b60035460408051636416c18360e01b81526001600160a01b038086166004830152915185939290921691636416c18391602480820192602092909190829003018186803b15801561152757600080fd5b505afa15801561153b573d6000803e3d6000fd5b505050506040513d602081101561155157600080fd5b505161159a576040805162461bcd60e51b81526020600482015260136024820152721513d2d15397d393d517d4d5541413d4951151606a1b604482015290519081900360640190fd5b610f27848484600460009054906101000a90046001600160a01b03166001600160a01b0316635391f48360016040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156115fc57600080fd5b505af1158015611610573d6000803e3d6000fd5b505050506040513d602081101561162657600080fd5b505161178d565b60408051632142170760e11b81526001600160a01b038581166004830152306024830152604482018490529151918416916342842e0e9160648082019260009290919082900301818387803b15801561168557600080fd5b505af1158015611699573d6000803e3d6000fd5b50505050505050565b6002546001600160a01b031633146114275760405162461bcd60e51b8152600401808060200182810382526026815260200180611f6b6026913960400191505060405180910390fd5b600154600160a01b900460ff1615611427576040805162461bcd60e51b81526020600482015260066024820152651b1bd8dad95960d21b604482015290519081900360640190fd5b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052610f27908590611e04565b60035460408051646d6174696360d81b8152815190819003600501812063cac39a0560e01b8252600482015290516000926001600160a01b03169163cac39a05916024808301926020929190829003018186803b1580156117ed57600080fd5b505afa158015611801573d6000803e3d6000fd5b505050506040513d602081101561181757600080fd5b505190506001600160a01b03848116908216141561183d5761183883611ac1565b6118dd565b6003805460408051621c1bdb60ea1b8152815190819003909301832063cac39a0560e01b84526004840152516001600160a01b039091169163cac39a05916024808301926020929190829003018186803b15801561189a57600080fd5b505afa1580156118ae573d6000803e3d6000fd5b505050506040513d60208110156118c457600080fd5b50516001600160a01b03858116911614156118dd578093505b604080518082018252606087811b6bffffffffffffffffffffffff199081168284015287821b16607483015260888083018790528351808403909101815260a883018452805160209182012083524281840190815260008781526006835285812094518555905160019094019390935560055460075485516001600160a01b03808d1682860152808c16828901529481018a905260808082018a90528751808303909101815260a082018089526316f1983160e01b905291851660a4820181815260c48301988952835160e4840152835196909416976316f198319791969395909361010490930192908601918190849084905b838110156119e95781810151838201526020016119d1565b50505050905090810190601f168015611a165780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015611a3657600080fd5b505af1158015611a4a573d6000803e3d6000fd5b50505050836001600160a01b0316856001600160a01b03167f1dadc8d0683c6f9824e885935c1bec6f76816730dcec148dda8cf25a7b9f797b8585604051808381526020018281526020019250505060405180910390a35050505050565b600082820183811015611aba57600080fd5b9392505050565b60035460408051646d6174696360d81b8152815190819003600501812063cac39a0560e01b8252600482015290516000926001600160a01b03169163cac39a05916024808301926020929190829003018186803b158015611b2157600080fd5b505afa158015611b35573d6000803e3d6000fd5b505050506040513d6020811015611b4b57600080fd5b5051600354604080516f3837b63cb3b7b726b4b3b930ba34b7b760811b8152815190819003601001812063cac39a0560e01b8252600482015290519293506000926001600160a01b039092169163cac39a0591602480820192602092909190829003018186803b158015611bbe57600080fd5b505afa158015611bd2573d6000803e3d6000fd5b505050506040513d6020811015611be857600080fd5b5051604080516370a0823160e01b8152306004820152905191925084916001600160a01b038516916370a08231916024808301926020929190829003018186803b158015611c3557600080fd5b505afa158015611c49573d6000803e3d6000fd5b505050506040513d6020811015611c5f57600080fd5b50511015611c9e5760405162461bcd60e51b815260040180806020018281038252602c815260200180611f01602c913960400191505060405180910390fd5b816001600160a01b031663095ea7b382856040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015611cfe57600080fd5b505af1158015611d12573d6000803e3d6000fd5b505050506040513d6020811015611d2857600080fd5b5050604080516308a960c160e31b81526004810185905290516001600160a01b0383169163454b060891602480830192600092919082900301818387803b15801561168557600080fd5b6001805460ff60a01b19169055565b6001600160a01b038116611d9457600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6001805460ff60a01b1916600160a01b179055565b611e16826001600160a01b0316611efa565b611e1f57600080fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310611e5d5780518252601f199092019160209182019101611e3e565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611ebf576040519150601f19603f3d011682016040523d82523d6000602084013e611ec4565b606091505b509150915081611ed357600080fd5b805115610f2757808060200190516020811015611eef57600080fd5b5051610f2757600080fd5b3b15159056fe616d6f756e742065786365656473207468697320636f6e74726163742773204d415449432062616c616e636541746c65617374206f6e65206f6620737461746553656e646572206f72206368696c64436861696e20616464726573732073686f756c64206368616e67654f6e6c7920676f7665726e616e636520636f6e747261637420697320617574686f72697a6564a265627a7a72315820c1dbd9f6fea99031eca29e23c9ebb67c5314bf5383a338b9419970be48a5842664736f6c63430005110032
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.