ETH Price: $3,366.05 (-1.62%)
Gas: 6.16 Gwei

Contract

0x806a196872Beff0CDE5663cbc1d8962309444932
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0x6080604091171282019-12-16 19:53:231807 days ago1576526003IN
 Create: rDAI
0 ETH0.011873983

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
rDAI

Compiler Version
v0.5.12+commit.7709ece9

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2019-12-16
*/

pragma solidity >=0.5.10 <0.6.0;
pragma experimental ABIEncoderV2;


contract Proxiable {
    

    function updateCodeAddress(address newAddress) internal {
        require(
            bytes32(
                    0xc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf7
                ) ==
                Proxiable(newAddress).proxiableUUID(),
            "Not compatible"
        );
        assembly {
            
            sstore(
                0xc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf7,
                newAddress
            )
        }
    }
    function proxiableUUID() public pure returns (bytes32) {
        return
            0xc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf7;
    }
}

contract RTokenStructs {
    
    struct GlobalStats {
        
        uint256 totalSupply;
        
        uint256 totalSavingsAmount;
    }


    
    struct AccountStatsView {
        
        uint256 hatID;
        
        uint256 rAmount;
        
        uint256 rInterest;
        
        uint256 lDebt;
        
        uint256 sInternalAmount;
        
        uint256 rInterestPayable;
        
        uint256 cumulativeInterest;
    }

    
    struct AccountStatsStored {
        
        uint256 cumulativeInterest;
    }

    
    struct HatStatsView {
        
        uint256 useCount;
        
        uint256 totalLoans;
        
        uint256 totalSavings;
    }

    
    struct HatStatsStored {
        
        uint256 useCount;
        
        uint256 totalLoans;
        
        uint256 totalInternalSavings;
    }

    
    struct Hat {
        address[] recipients;
        uint32[] proportions;
    }

    
    struct Account {
        uint256 hatID;
        uint256 rAmount;
        uint256 rInterest;
        mapping(address => uint256) lRecipients;
        uint256 lDebt;
        uint256 sInternalAmount;
    }
}

interface IERC20 {
    
    function totalSupply() external view returns (uint256);

    
    function balanceOf(address account) external view returns (uint256);

    
    function transfer(address recipient, uint256 amount) external returns (bool);

    
    function allowance(address owner, address spender) external view returns (uint256);

    
    function approve(address spender, uint256 amount) external returns (bool);

    
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    
    event Transfer(address indexed from, address indexed to, uint256 value);

    
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

interface IAllocationStrategy {

    
    function underlying() external view returns (address);

    
    function exchangeRateStored() external view returns (uint256);

    
    function accrueInterest() external returns (bool);

    
    function investUnderlying(uint256 investAmount) external returns (uint256);

    
    function redeemUnderlying(uint256 redeemAmount) external returns (uint256);

}

contract RTokenStorage is RTokenStructs, IERC20 {
    
    address public _owner;
    bool public initialized;
    
    uint256 public _guardCounter;
    
    string public name;
    
    string public symbol;
    
    uint256 public decimals;
    
    uint256 public totalSupply;
    
    IAllocationStrategy public ias;
    
    IERC20 public token;
    
    
    uint256 public savingAssetOrignalAmount;
    
    
    
    
    
    
    
    
    
    
    
    
    
    uint256 public savingAssetConversionRate;
    
    mapping(address => mapping(address => uint256)) public transferAllowances;
    
    Hat[] internal hats;
    
    mapping(address => Account) public accounts;
    
    mapping(address => AccountStatsStored) public accountStats;
    
    mapping(uint256 => HatStatsStored) public hatStats;
}

contract Ownable is RTokenStorage {
    event OwnershipTransferred(
        address indexed previousOwner,
        address indexed newOwner
    );

    
    constructor() internal {
        _owner = msg.sender;
        emit OwnershipTransferred(address(0), _owner);
    }

    
    function owner() public view returns (address) {
        return _owner;
    }

    
    modifier onlyOwner() {
        require(isOwner(), "Ownable: caller is not the owner");
        _;
    }

    
    function isOwner() public view returns (bool) {
        return msg.sender == _owner;
    }

    
    function renounceOwnership() public onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    
    function transferOwnership(address newOwner) public onlyOwner {
        _transferOwnership(newOwner);
    }

    
    function _transferOwnership(address newOwner) internal {
        require(
            newOwner != address(0),
            "Ownable: new owner is the zero address"
        );
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

contract LibraryLock is RTokenStorage {
    
    

    modifier delegatedOnly() {
        require(
            initialized == true,
            "The library is locked. No direct 'call' is allowed."
        );
        _;
    }
    function initialize() internal {
        initialized = true;
    }
}

library SafeMath {
    
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        
        
        
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        
        require(b > 0, errorMessage);
        uint256 c = a / b;
        

        return c;
    }

    
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

contract ReentrancyGuard is RTokenStorage {
    
    modifier nonReentrant() {
        _guardCounter += 1;
        uint256 localCounter = _guardCounter;
        _;
        require(
            localCounter == _guardCounter,
            "ReentrancyGuard: reentrant call"
        );
    }
}

contract IRToken is RTokenStructs, IERC20 {
    
    
    
    
    function mint(uint256 mintAmount) external returns (bool);

    
    function mintWithSelectedHat(uint256 mintAmount, uint256 hatID)
        external
        returns (bool);

    
    function mintWithNewHat(
        uint256 mintAmount,
        address[] calldata recipients,
        uint32[] calldata proportions
    ) external returns (bool);

    
    function transferAll(address dst) external returns (bool);

    
    function transferAllFrom(address src, address dst) external returns (bool);

    
    function redeem(uint256 redeemTokens) external returns (bool);

    
    function redeemAll() external returns (bool);

    
    function redeemAndTransfer(address redeemTo, uint256 redeemTokens)
        external
        returns (bool);

    
    function redeemAndTransferAll(address redeemTo) external returns (bool);

    
    function createHat(
        address[] calldata recipients,
        uint32[] calldata proportions,
        bool doChangeHat
    ) external returns (uint256 hatID);

    
    function changeHat(uint256 hatID) external returns (bool);

    
    function payInterest(address owner) external returns (bool);

    
    
    
    
    function getMaximumHatID() external view returns (uint256 hatID);

    
    function getHatByAddress(address owner)
        external
        view
        returns (
            uint256 hatID,
            address[] memory recipients,
            uint32[] memory proportions
        );

    
    function getHatByID(uint256 hatID)
        external
        view
        returns (address[] memory recipients, uint32[] memory proportions);

    
    function receivedSavingsOf(address owner)
        external
        view
        returns (uint256 amount);

    
    function receivedLoanOf(address owner)
        external
        view
        returns (uint256 amount);

    
    function interestPayableOf(address owner)
        external
        view
        returns (uint256 amount);

    
    
    
    
    function getCurrentSavingStrategy() external view returns (address);

    
    function getSavingAssetBalance()
        external
        view
        returns (uint256 rAmount, uint256 sOriginalAmount);

    
    function getGlobalStats() external view returns (GlobalStats memory);

    
    function getAccountStats(address owner)
        external
        view
        returns (AccountStatsView memory);

    
    function getHatStats(uint256 hatID)
        external
        view
        returns (HatStatsView memory);

    
    
    
    
    event LoansTransferred(
        address indexed owner,
        address indexed recipient,
        uint256 indexed hatId,
        bool isDistribution,
        uint256 redeemableAmount,
        uint256 internalSavingsAmount);

    
    event InterestPaid(address indexed recipient, uint256 amount);

    
    event HatCreated(uint256 indexed hatID);

    
    event HatChanged(address indexed account, uint256 indexed oldHatID, uint256 indexed newHatID);
}

interface IRTokenAdmin {

    
    function owner() external view returns (address);

    
    function transferOwnership(address newOwner) external;

    
    function getCurrentAllocationStrategy()
        external view returns (address allocationStrategy);

    
    function changeAllocationStrategy(address allocationStrategy)
        external;

    
    function changeHatFor(address contractAddress, uint256 hatID)
        external;

    
    function updateCode(address newCode) external;

    
    event CodeUpdated(address newCode);

    
    event AllocationStrategyChanged(address strategy, uint256 conversionRate);
}

contract RToken is
    RTokenStorage,
    IRToken,
    IRTokenAdmin,
    Ownable,
    Proxiable,
    LibraryLock,
    ReentrancyGuard {
    using SafeMath for uint256;


    uint256 public constant ALLOCATION_STRATEGY_EXCHANGE_RATE_SCALE = 1e18;
    uint256 public constant INITIAL_SAVING_ASSET_CONVERSION_RATE = 1e18;
    uint256 public constant MAX_UINT256 = uint256(int256(-1));
    uint256 public constant SELF_HAT_ID = MAX_UINT256;
    uint32 public constant PROPORTION_BASE = 0xFFFFFFFF;
    uint256 public constant MAX_NUM_HAT_RECIPIENTS = 50;

    
    function initialize(
        IAllocationStrategy allocationStrategy,
        string memory name_,
        string memory symbol_,
        uint256 decimals_) public {
        require(!initialized, "The library has already been initialized.");
        LibraryLock.initialize();
        _owner = msg.sender;
        _guardCounter = 1;
        name = name_;
        symbol = symbol_;
        decimals = decimals_;
        savingAssetConversionRate = INITIAL_SAVING_ASSET_CONVERSION_RATE;
        ias = allocationStrategy;
        token = IERC20(ias.underlying());

        
        hats.push(Hat(new address[](0), new uint32[](0)));

        
        hatStats[0].useCount = MAX_UINT256;

        emit AllocationStrategyChanged(address(ias), savingAssetConversionRate);
    }

    
    
    

    
    function balanceOf(address owner) external view returns (uint256) {
        return accounts[owner].rAmount;
    }

    
    function allowance(address owner, address spender)
        external
        view
        returns (uint256)
    {
        return transferAllowances[owner][spender];
    }

    
    function approve(address spender, uint256 amount) external returns (bool) {
        address src = msg.sender;
        transferAllowances[src][spender] = amount;
        emit Approval(src, spender, amount);
        return true;
    }

    
    function transfer(address dst, uint256 amount)
        external
        nonReentrant
        returns (bool)
    {
        address src = msg.sender;
        payInterestInternal(src);
        transferInternal(src, src, dst, amount);
        payInterestInternal(dst);
        return true;
    }

    
    function transferAll(address dst) external nonReentrant returns (bool) {
        address src = msg.sender;
        payInterestInternal(src);
        transferInternal(src, src, dst, accounts[src].rAmount);
        payInterestInternal(dst);
        return true;
    }

    
    function transferAllFrom(address src, address dst)
        external
        nonReentrant
        returns (bool)
    {
        payInterestInternal(src);
        transferInternal(msg.sender, src, dst, accounts[src].rAmount);
        payInterestInternal(dst);
        return true;
    }

    
    function transferFrom(address src, address dst, uint256 amount)
        external
        nonReentrant
        returns (bool)
    {
        payInterestInternal(src);
        transferInternal(msg.sender, src, dst, amount);
        payInterestInternal(dst);
        return true;
    }

    
    
    

    
    function mint(uint256 mintAmount) external nonReentrant returns (bool) {
        mintInternal(mintAmount);
        payInterestInternal(msg.sender);
        return true;
    }

    
    function mintWithSelectedHat(uint256 mintAmount, uint256 hatID)
        external
        nonReentrant
        returns (bool)
    {
        changeHatInternal(msg.sender, hatID);
        mintInternal(mintAmount);
        payInterestInternal(msg.sender);
        return true;
    }

    
    function mintWithNewHat(
        uint256 mintAmount,
        address[] calldata recipients,
        uint32[] calldata proportions
    ) external nonReentrant returns (bool) {
        uint256 hatID = createHatInternal(recipients, proportions);
        changeHatInternal(msg.sender, hatID);
        mintInternal(mintAmount);
        payInterestInternal(msg.sender);
        return true;
    }

    
    function redeem(uint256 redeemTokens) external nonReentrant returns (bool) {
        address src = msg.sender;
        payInterestInternal(src);
        redeemInternal(src, redeemTokens);
        return true;
    }

    
    function redeemAll() external nonReentrant returns (bool) {
        address src = msg.sender;
        payInterestInternal(src);
        redeemInternal(src, accounts[src].rAmount);
        return true;
    }

    
    function redeemAndTransfer(address redeemTo, uint256 redeemTokens)
        external
        nonReentrant
        returns (bool)
    {
        address src = msg.sender;
        payInterestInternal(src);
        redeemInternal(redeemTo, redeemTokens);
        return true;
    }

    
    function redeemAndTransferAll(address redeemTo)
        external
        nonReentrant
        returns (bool)
    {
        address src = msg.sender;
        payInterestInternal(src);
        redeemInternal(redeemTo, accounts[src].rAmount);
        return true;
    }

    
    function createHat(
        address[] calldata recipients,
        uint32[] calldata proportions,
        bool doChangeHat
    ) external nonReentrant returns (uint256 hatID) {
        hatID = createHatInternal(recipients, proportions);
        if (doChangeHat) {
            changeHatInternal(msg.sender, hatID);
        }
    }

    
    function changeHat(uint256 hatID) external nonReentrant returns (bool) {
        changeHatInternal(msg.sender, hatID);
        payInterestInternal(msg.sender);
        return true;
    }

    
    function getMaximumHatID() external view returns (uint256 hatID) {
        return hats.length - 1;
    }

    
    function getHatByAddress(address owner)
        external
        view
        returns (
            uint256 hatID,
            address[] memory recipients,
            uint32[] memory proportions
        )
    {
        hatID = accounts[owner].hatID;
        (recipients, proportions) = _getHatByID(hatID);
    }

    
    function getHatByID(uint256 hatID)
        external
        view
        returns (address[] memory recipients, uint32[] memory proportions) {
        (recipients, proportions) = _getHatByID(hatID);
    }

    function _getHatByID(uint256 hatID)
        private
        view
        returns (address[] memory recipients, uint32[] memory proportions) {
        if (hatID != 0 && hatID != SELF_HAT_ID) {
            Hat memory hat = hats[hatID];
            recipients = hat.recipients;
            proportions = hat.proportions;
        } else {
            recipients = new address[](0);
            proportions = new uint32[](0);
        }
    }

    
    function receivedSavingsOf(address owner)
        external
        view
        returns (uint256 amount)
    {
        Account storage account = accounts[owner];
        uint256 rGross = sInternalToR(account.sInternalAmount);
        return rGross;
    }

    
    function receivedLoanOf(address owner)
        external
        view
        returns (uint256 amount)
    {
        Account storage account = accounts[owner];
        return account.lDebt;
    }

    
    function interestPayableOf(address owner)
        external
        view
        returns (uint256 amount)
    {
        Account storage account = accounts[owner];
        return getInterestPayableOf(account);
    }

    
    function payInterest(address owner) external nonReentrant returns (bool) {
        payInterestInternal(owner);
        return true;
    }

    
    function getGlobalStats() external view returns (GlobalStats memory) {
        uint256 totalSavingsAmount;
        totalSavingsAmount += sOriginalToR(savingAssetOrignalAmount);
        return
            GlobalStats({
                totalSupply: totalSupply,
                totalSavingsAmount: totalSavingsAmount
            });
    }

    
    function getAccountStats(address owner)
        external
        view
        returns (AccountStatsView memory stats)
    {
        Account storage account = accounts[owner];
        stats.hatID = account.hatID;
        stats.rAmount = account.rAmount;
        stats.rInterest = account.rInterest;
        stats.lDebt = account.lDebt;
        stats.sInternalAmount = account.sInternalAmount;

        stats.rInterestPayable = getInterestPayableOf(account);

        AccountStatsStored storage statsStored = accountStats[owner];
        stats.cumulativeInterest = statsStored.cumulativeInterest;

        return stats;
    }

    
    function getHatStats(uint256 hatID)
        external
        view
        returns (HatStatsView memory stats) {
        HatStatsStored storage statsStored = hatStats[hatID];
        stats.useCount = statsStored.useCount;
        stats.totalLoans = statsStored.totalLoans;

        stats.totalSavings = sInternalToR(statsStored.totalInternalSavings);
        return stats;
    }

    
    function getCurrentSavingStrategy() external view returns (address) {
        return address(ias);
    }

    
    function getSavingAssetBalance()
        external
        view
        returns (uint256 rAmount, uint256 sOriginalAmount)
    {
        sOriginalAmount = savingAssetOrignalAmount;
        rAmount = sOriginalToR(sOriginalAmount);
    }

    
    function changeAllocationStrategy(address allocationStrategy_)
        external
        nonReentrant
        onlyOwner
    {
        IAllocationStrategy allocationStrategy = IAllocationStrategy(allocationStrategy_);
        require(
            allocationStrategy.underlying() == address(token),
            "New strategy should have the same underlying asset"
        );
        IAllocationStrategy oldIas = ias;
        ias = allocationStrategy;
        
        uint256 sOriginalBurned = oldIas.redeemUnderlying(totalSupply);
        
        require(token.approve(address(ias), totalSupply), "token approve failed");
        uint256 sOriginalCreated = ias.investUnderlying(totalSupply);

        
        
        
        
        
        
        
        
        
        
        
        
        uint256 savingAssetConversionRateOld = savingAssetConversionRate;
        savingAssetConversionRate = sOriginalBurned
            .mul(savingAssetConversionRateOld)
            .div(sOriginalCreated);

        emit AllocationStrategyChanged(allocationStrategy_, savingAssetConversionRate);
    }

    
    function getCurrentAllocationStrategy()
        external view returns (address allocationStrategy) {
        return address(ias);
    }

    
    function changeHatFor(address contractAddress, uint256 hatID) external onlyOwner {
        require(_isContract(contractAddress), "Admin can only change hat for contract address");
        changeHatInternal(contractAddress, hatID);
    }

    
    function updateCode(address newCode) external onlyOwner delegatedOnly {
        updateCodeAddress(newCode);
        emit CodeUpdated(newCode);
    }

    
    function transferInternal(
        address spender,
        address src,
        address dst,
        uint256 tokens
    ) internal {
        require(src != dst, "src should not equal dst");

        require(
            accounts[src].rAmount >= tokens,
            "Not enough balance to transfer"
        );

        
        uint256 startingAllowance = 0;
        if (spender == src) {
            startingAllowance = MAX_UINT256;
        } else {
            startingAllowance = transferAllowances[src][spender];
        }
        require(
            startingAllowance >= tokens,
            "Not enough allowance for transfer"
        );

        
        uint256 allowanceNew = startingAllowance.sub(tokens);
        uint256 srcTokensNew = accounts[src].rAmount.sub(tokens);
        uint256 dstTokensNew = accounts[dst].rAmount.add(tokens);

        
        
        

        
        bool sameHat = accounts[src].hatID == accounts[dst].hatID;

        
        if ((accounts[src].hatID != 0 &&
            accounts[dst].hatID == 0 &&
            accounts[src].hatID != SELF_HAT_ID)) {
            changeHatInternal(dst, accounts[src].hatID);
        }

        accounts[src].rAmount = srcTokensNew;
        accounts[dst].rAmount = dstTokensNew;

        
        if (startingAllowance != MAX_UINT256) {
            transferAllowances[src][spender] = allowanceNew;
        }

        
        if (!sameHat) {
            uint256 sInternalAmountCollected = estimateAndRecollectLoans(
                src,
                tokens
            );
            distributeLoans(dst, tokens, sInternalAmountCollected);
        } else {
            
            sameHatTransfer(src, dst, accounts[src].hatID, tokens);
        }

        
        
        
        
        
        if (accounts[src].rInterest > accounts[src].rAmount) {
            accounts[src].rInterest = accounts[src].rAmount;
        }

        
        emit Transfer(src, dst, tokens);
    }

    
    function mintInternal(uint256 mintAmount) internal {
        require(
            token.allowance(msg.sender, address(this)) >= mintAmount,
            "Not enough allowance"
        );

        Account storage account = accounts[msg.sender];

        
        require(token.transferFrom(msg.sender, address(this), mintAmount), "token transfer failed");
        require(token.approve(address(ias), mintAmount), "token approve failed");
        uint256 sOriginalCreated = ias.investUnderlying(mintAmount);

        
        totalSupply = totalSupply.add(mintAmount);
        account.rAmount = account.rAmount.add(mintAmount);

        
        savingAssetOrignalAmount = savingAssetOrignalAmount.add(sOriginalCreated);

        
        uint256 sInternalCreated = sOriginalToSInternal(sOriginalCreated);
        distributeLoans(msg.sender, mintAmount, sInternalCreated);

        emit Transfer(address(0), msg.sender, mintAmount);
    }

    
    function redeemInternal(address redeemTo, uint256 redeemAmount) internal {
        Account storage account = accounts[msg.sender];
        require(redeemAmount > 0, "Redeem amount cannot be zero");
        require(
            redeemAmount <= account.rAmount,
            "Not enough balance to redeem"
        );

        uint256 sOriginalBurned = redeemAndRecollectLoans(
            msg.sender,
            redeemAmount
        );

        
        account.rAmount = account.rAmount.sub(redeemAmount);
        if (account.rInterest > account.rAmount) {
            account.rInterest = account.rAmount;
        }
        totalSupply = totalSupply.sub(redeemAmount);

        
        if (savingAssetOrignalAmount > sOriginalBurned) {
            savingAssetOrignalAmount -= sOriginalBurned;
        } else {
            savingAssetOrignalAmount = 0;
        }

        
        require(token.transfer(redeemTo, redeemAmount), "token transfer failed");

        emit Transfer(msg.sender, address(0), redeemAmount);
    }

    
    function createHatInternal(
        address[] memory recipients,
        uint32[] memory proportions
    ) internal returns (uint256 hatID) {
        uint256 i;

        require(recipients.length > 0, "Invalid hat: at least one recipient");
        require(recipients.length <= MAX_NUM_HAT_RECIPIENTS, "Invalild hat: maximum number of recipients reached");
        require(
            recipients.length == proportions.length,
            "Invalid hat: length not matching"
        );

        
        
        
        uint256 totalProportions = 0;
        for (i = 0; i < recipients.length; ++i) {
            require(
                proportions[i] > 0,
                "Invalid hat: proportion should be larger than 0"
            );
            require(recipients[i] != address(0), "Invalid hat: recipient should not be 0x0");
            
            totalProportions += uint256(proportions[i]);
        }
        for (i = 0; i < proportions.length; ++i) {
            proportions[i] = uint32(
                
                (uint256(proportions[i]) * uint256(PROPORTION_BASE)) /
                    totalProportions
            );
        }

        hatID = hats.push(Hat(recipients, proportions)) - 1;
        emit HatCreated(hatID);
    }

    
    function changeHatInternal(address owner, uint256 hatID) internal {
        require(hatID == SELF_HAT_ID || hatID < hats.length, "Invalid hat ID");
        Account storage account = accounts[owner];
        uint256 oldHatID = account.hatID;
        HatStatsStored storage oldHatStats = hatStats[oldHatID];
        HatStatsStored storage newHatStats = hatStats[hatID];
        if (account.rAmount > 0) {
            uint256 sInternalAmountCollected = estimateAndRecollectLoans(
                owner,
                account.rAmount
            );
            account.hatID = hatID;
            distributeLoans(owner, account.rAmount, sInternalAmountCollected);
        } else {
            account.hatID = hatID;
        }
        oldHatStats.useCount -= 1;
        newHatStats.useCount += 1;
        emit HatChanged(owner, oldHatID, hatID);
    }

    
    function getInterestPayableOf(Account storage account)
        internal
        view
        returns (uint256)
    {
        uint256 rGross = sInternalToR(account.sInternalAmount);
        if (rGross > (account.lDebt.add(account.rInterest))) {
            
            return rGross - account.lDebt - account.rInterest;
        } else {
            
            return 0;
        }
    }

    
    function distributeLoans(
        address owner,
        uint256 rAmount,
        uint256 sInternalAmount
    ) internal {
        Account storage account = accounts[owner];
        Hat storage hat = hats[account.hatID == SELF_HAT_ID
            ? 0
            : account.hatID];
        uint256 i;
        if (hat.recipients.length > 0) {
            uint256 rLeft = rAmount;
            uint256 sInternalLeft = sInternalAmount;
            for (i = 0; i < hat.proportions.length; ++i) {
                address recipientAddress = hat.recipients[i];
                Account storage recipientAccount = accounts[recipientAddress];
                bool isLastRecipient = i == (hat.proportions.length - 1);

                
                uint256 lDebtRecipient = isLastRecipient
                    ? rLeft
                    : (rAmount.mul(hat.proportions[i])) / PROPORTION_BASE;
                
                account.lRecipients[recipientAddress] = account.lRecipients[recipientAddress]
                    .add(lDebtRecipient);
                recipientAccount.lDebt = recipientAccount.lDebt
                    .add(lDebtRecipient);
                
                rLeft = gentleSub(rLeft, lDebtRecipient);

                
                uint256 sInternalAmountRecipient = isLastRecipient
                    ? sInternalLeft
                    : (sInternalAmount.mul(hat.proportions[i])) / PROPORTION_BASE;
                recipientAccount.sInternalAmount = recipientAccount.sInternalAmount
                    .add(sInternalAmountRecipient);
                
                sInternalLeft = gentleSub(sInternalLeft, sInternalAmountRecipient);

                _updateLoanStats(owner, recipientAddress, account.hatID, true, lDebtRecipient, sInternalAmountRecipient);
            }
        } else {
            
            account.lDebt = account.lDebt.add(rAmount);
            account.sInternalAmount = account.sInternalAmount
                .add(sInternalAmount);

            _updateLoanStats(owner, owner, account.hatID, true, rAmount, sInternalAmount);
        }
    }

    
    function estimateAndRecollectLoans(address owner, uint256 rAmount)
        internal
        returns (uint256 sInternalAmount)
    {
        
        require(ias.accrueInterest(), "accrueInterest failed");
        sInternalAmount = rToSInternal(rAmount);
        recollectLoans(owner, rAmount, sInternalAmount);
    }

    
    function redeemAndRecollectLoans(address owner, uint256 rAmount)
        internal
        returns (uint256 sOriginalBurned)
    {
        sOriginalBurned = ias.redeemUnderlying(rAmount);
        uint256 sInternalBurned = sOriginalToSInternal(sOriginalBurned);
        recollectLoans(owner, rAmount, sInternalBurned);
    }

    
    function recollectLoans(
        address owner,
        uint256 rAmount,
        uint256 sInternalAmount
    ) internal {
        Account storage account = accounts[owner];
        Hat storage hat = hats[account.hatID == SELF_HAT_ID
            ? 0
            : account.hatID];
        if (hat.recipients.length > 0) {
            uint256 rLeft = rAmount;
            uint256 sInternalLeft = sInternalAmount;
            uint256 i;
            for (i = 0; i < hat.proportions.length; ++i) {
                address recipientAddress = hat.recipients[i];
                Account storage recipientAccount = accounts[recipientAddress];
                bool isLastRecipient = i == (hat.proportions.length - 1);

                
                uint256 lDebtRecipient = isLastRecipient
                    ? rLeft
                    : (rAmount.mul(hat.proportions[i])) / PROPORTION_BASE;
                recipientAccount.lDebt = gentleSub(
                    recipientAccount.lDebt,
                    lDebtRecipient);
                account.lRecipients[recipientAddress] = gentleSub(
                    account.lRecipients[recipientAddress],
                    lDebtRecipient);
                
                rLeft = gentleSub(rLeft, lDebtRecipient);

                
                uint256 sInternalAmountRecipient = isLastRecipient
                    ? sInternalLeft
                    : (sInternalAmount.mul(hat.proportions[i])) / PROPORTION_BASE;
                recipientAccount.sInternalAmount = gentleSub(
                    recipientAccount.sInternalAmount,
                    sInternalAmountRecipient);
                
                sInternalLeft = gentleSub(sInternalLeft, sInternalAmountRecipient);

                _updateLoanStats(owner, recipientAddress, account.hatID, false, lDebtRecipient, sInternalAmountRecipient);
            }
        } else {
            
            account.lDebt = gentleSub(account.lDebt, rAmount);
            account.sInternalAmount = gentleSub(account.sInternalAmount, sInternalAmount);

            _updateLoanStats(owner, owner, account.hatID, false, rAmount, sInternalAmount);
        }
    }

    
    function sameHatTransfer(
        address src,
        address dst,
        uint256 hatID,
        uint256 rAmount) internal {
        
        require(ias.accrueInterest(), "accrueInterest failed");

        Account storage srcAccount = accounts[src];
        Account storage dstAccount = accounts[dst];

        uint256 sInternalAmount = rToSInternal(rAmount);

        srcAccount.lDebt = gentleSub(srcAccount.lDebt, rAmount);
        srcAccount.sInternalAmount = gentleSub(srcAccount.sInternalAmount, sInternalAmount);
        _updateLoanStats(src, src, hatID, false, rAmount, sInternalAmount);

        dstAccount.lDebt = dstAccount.lDebt.add(rAmount);
        dstAccount.sInternalAmount = dstAccount.sInternalAmount.add(sInternalAmount);
        _updateLoanStats(dst, dst, hatID, true, rAmount, sInternalAmount);
    }

    
    function payInterestInternal(address owner) internal {
        Account storage account = accounts[owner];
        AccountStatsStored storage stats = accountStats[owner];

        require(ias.accrueInterest(), "accrueInterest failed");
        uint256 interestAmount = getInterestPayableOf(account);

        if (interestAmount > 0) {
            stats.cumulativeInterest = stats
                .cumulativeInterest
                .add(interestAmount);
            account.rInterest = account.rInterest.add(interestAmount);
            account.rAmount = account.rAmount.add(interestAmount);
            totalSupply = totalSupply.add(interestAmount);
            emit InterestPaid(owner, interestAmount);
            emit Transfer(address(0), owner, interestAmount);
        }
    }

    function _updateLoanStats(
        address owner,
        address recipient,
        uint256 hatID,
        bool isDistribution,
        uint256 redeemableAmount,
        uint256 sInternalAmount) private {
        HatStatsStored storage hatStats = hatStats[hatID];

        emit LoansTransferred(owner, recipient, hatID,
            isDistribution,
            redeemableAmount,
            sInternalAmount);

        if (isDistribution) {
            hatStats.totalLoans = hatStats.totalLoans.add(redeemableAmount);
            hatStats.totalInternalSavings = hatStats.totalInternalSavings
                .add(sInternalAmount);
        } else {
            hatStats.totalLoans = gentleSub(hatStats.totalLoans, redeemableAmount);
            hatStats.totalInternalSavings = gentleSub(
                hatStats.totalInternalSavings,
                sInternalAmount);
        }
    }

    function _isContract(address addr) private view returns (bool) {
      uint size;
      assembly { size := extcodesize(addr) }
      return size > 0;
    }

    
    function gentleSub(uint256 a, uint256 b) private pure returns (uint256) {
        if (a < b) return 0;
        else return a - b;
    }

    
    function sInternalToR(uint256 sInternalAmount)
        private view
        returns (uint256 rAmount) {
        
        
        
        
        
        
        
        return sInternalAmount
            .mul(ias.exchangeRateStored())
            .div(savingAssetConversionRate);
    }

    
    function rToSInternal(uint256 rAmount)
        private view
        returns (uint256 sInternalAmount) {
        return rAmount
            .mul(savingAssetConversionRate)
            .div(ias.exchangeRateStored());
    }

    
    function sOriginalToR(uint sOriginalAmount)
        private view
        returns (uint256 sInternalAmount) {
        return sOriginalAmount
            .mul(ias.exchangeRateStored())
            .div(ALLOCATION_STRATEGY_EXCHANGE_RATE_SCALE);
    }

    
    function sOriginalToSInternal(uint sOriginalAmount)
        private view
        returns (uint256 sInternalAmount) {
        
        return sOriginalAmount
            .mul(savingAssetConversionRate)
            .div(ALLOCATION_STRATEGY_EXCHANGE_RATE_SCALE);
    }
}

contract rDAI is RToken {

    function initialize (
        IAllocationStrategy allocationStrategy) external {
        RToken.initialize(allocationStrategy,
            "Redeemable DAI",
            "rDAI",
            18);
    }

}

Contract Security Audit

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"strategy","type":"address"},{"indexed":false,"internalType":"uint256","name":"conversionRate","type":"uint256"}],"name":"AllocationStrategyChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newCode","type":"address"}],"name":"CodeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"oldHatID","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"newHatID","type":"uint256"}],"name":"HatChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"hatID","type":"uint256"}],"name":"HatCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"InterestPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":true,"internalType":"uint256","name":"hatId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isDistribution","type":"bool"},{"indexed":false,"internalType":"uint256","name":"redeemableAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"internalSavingsAmount","type":"uint256"}],"name":"LoansTransferred","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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"constant":true,"inputs":[],"name":"ALLOCATION_STRATEGY_EXCHANGE_RATE_SCALE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"INITIAL_SAVING_ASSET_CONVERSION_RATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MAX_NUM_HAT_RECIPIENTS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MAX_UINT256","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"PROPORTION_BASE","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SELF_HAT_ID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_guardCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"accountStats","outputs":[{"internalType":"uint256","name":"cumulativeInterest","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"accounts","outputs":[{"internalType":"uint256","name":"hatID","type":"uint256"},{"internalType":"uint256","name":"rAmount","type":"uint256"},{"internalType":"uint256","name":"rInterest","type":"uint256"},{"internalType":"uint256","name":"lDebt","type":"uint256"},{"internalType":"uint256","name":"sInternalAmount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"allocationStrategy_","type":"address"}],"name":"changeAllocationStrategy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"hatID","type":"uint256"}],"name":"changeHat","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"hatID","type":"uint256"}],"name":"changeHatFor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint32[]","name":"proportions","type":"uint32[]"},{"internalType":"bool","name":"doChangeHat","type":"bool"}],"name":"createHat","outputs":[{"internalType":"uint256","name":"hatID","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"getAccountStats","outputs":[{"components":[{"internalType":"uint256","name":"hatID","type":"uint256"},{"internalType":"uint256","name":"rAmount","type":"uint256"},{"internalType":"uint256","name":"rInterest","type":"uint256"},{"internalType":"uint256","name":"lDebt","type":"uint256"},{"internalType":"uint256","name":"sInternalAmount","type":"uint256"},{"internalType":"uint256","name":"rInterestPayable","type":"uint256"},{"internalType":"uint256","name":"cumulativeInterest","type":"uint256"}],"internalType":"struct RTokenStructs.AccountStatsView","name":"stats","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentAllocationStrategy","outputs":[{"internalType":"address","name":"allocationStrategy","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentSavingStrategy","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getGlobalStats","outputs":[{"components":[{"internalType":"uint256","name":"totalSupply","type":"uint256"},{"internalType":"uint256","name":"totalSavingsAmount","type":"uint256"}],"internalType":"struct RTokenStructs.GlobalStats","name":"","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"getHatByAddress","outputs":[{"internalType":"uint256","name":"hatID","type":"uint256"},{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint32[]","name":"proportions","type":"uint32[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"hatID","type":"uint256"}],"name":"getHatByID","outputs":[{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint32[]","name":"proportions","type":"uint32[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"hatID","type":"uint256"}],"name":"getHatStats","outputs":[{"components":[{"internalType":"uint256","name":"useCount","type":"uint256"},{"internalType":"uint256","name":"totalLoans","type":"uint256"},{"internalType":"uint256","name":"totalSavings","type":"uint256"}],"internalType":"struct RTokenStructs.HatStatsView","name":"stats","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getMaximumHatID","outputs":[{"internalType":"uint256","name":"hatID","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getSavingAssetBalance","outputs":[{"internalType":"uint256","name":"rAmount","type":"uint256"},{"internalType":"uint256","name":"sOriginalAmount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"hatStats","outputs":[{"internalType":"uint256","name":"useCount","type":"uint256"},{"internalType":"uint256","name":"totalLoans","type":"uint256"},{"internalType":"uint256","name":"totalInternalSavings","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ias","outputs":[{"internalType":"contract IAllocationStrategy","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"contract IAllocationStrategy","name":"allocationStrategy","type":"address"},{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"uint256","name":"decimals_","type":"uint256"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"contract IAllocationStrategy","name":"allocationStrategy","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"initialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"interestPayableOf","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"mintAmount","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"mintAmount","type":"uint256"},{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint32[]","name":"proportions","type":"uint32[]"}],"name":"mintWithNewHat","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"mintAmount","type":"uint256"},{"internalType":"uint256","name":"hatID","type":"uint256"}],"name":"mintWithSelectedHat","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"payInterest","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"receivedLoanOf","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"receivedSavingsOf","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"redeemTokens","type":"uint256"}],"name":"redeem","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"redeemAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"redeemTo","type":"address"},{"internalType":"uint256","name":"redeemTokens","type":"uint256"}],"name":"redeemAndTransfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"redeemTo","type":"address"}],"name":"redeemAndTransferAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"savingAssetConversionRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"savingAssetOrignalAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"dst","type":"address"}],"name":"transferAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"}],"name":"transferAllFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"transferAllowances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":[{"internalType":"address","name":"newCode","type":"address"}],"name":"updateCode","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]

60806040819052600080546001600160a01b03191633178082556001600160a01b0316917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3614636806100576000396000f3fe608060405234801561001057600080fd5b50600436106103a45760003560e01c806370a08231116101e9578063c034d0db1161010f578063d8884795116100ad578063f04bf8b31161007c578063f04bf8b314610757578063f2fde38b14610779578063fc0c546a1461078c578063fdbbf8ac14610794576103a4565b8063d888479514610713578063db006a7514610729578063dd62ed3e1461073c578063e192782b1461074f576103a4565b8063c4d66de8116100e9578063c4d66de8146106c7578063d007c644146106da578063d271be3f146106ed578063d3ac25c414610700576103a4565b8063c034d0db146104f5578063c1a2007d14610431578063c200659e146106bf576103a4565b80638f32d59b11610187578063a9059cbb11610156578063a9059cbb14610689578063b2bdfa7b1461069c578063b5dbfc1a146106a4578063bf5bfdfb146106b7576103a4565b80638f32d59b1461065357806395d89b411461065b578063a0712d6814610663578063a3a7e7f314610676576103a4565b806377ede051116101c357806377ede0511461062557806381c8d895146103d257806384d4b410146106385780638da5cb5b1461064b576103a4565b806370a0823114610602578063715018a61461061557806371ee46eb1461061d576103a4565b8063313ce567116102ce5780634d12d4b61161026c5780635cde50551161023b5780635cde5055146105a35780635e5c06e2146105b657806363152a50146105da5780636b4169c3146105ed576103a4565b80634d12d4b6146105535780634fd7c0dd1461056657806352d1902d14610586578063556043ef1461058e576103a4565b80633e20a929116102a85780633e20a9291461051057806346951954146105185780634929fbf71461052d578063496cc16414610540576103a4565b8063313ce567146104ed57806333a581d2146104f5578063388c0b8c146104fd576103a4565b8063158ef93e1161034657806323b872dd1161031557806323b872dd1461049f57806328cdfaeb146104b25780632f2ba814146104d25780632f4350c2146104e5576103a4565b8063158ef93e1461045957806318160ddd146104615780631cda95d514610469578063226e835c1461048a576103a4565b806306fdde031161038257806306fdde0314610409578063095ea7b31461041e57806310f3a6d81461043157806313e23e4114610446576103a4565b80630290cbc8146103a9578063039ab887146103d2578063054ab01a146103e7575b600080fd5b6103bc6103b736600461360c565b6107a7565b6040516103c99190614202565b60405180910390f35b6103da61081a565b6040516103c9919061422b565b6103fa6103f536600461360c565b610826565b6040516103c993929190614412565b610411610855565b6040516103c99190614247565b6103bc61042c3660046136cf565b6108e0565b61043961094e565b6040516103c99190614171565b6103da61045436600461360c565b61095e565b6103bc610980565b6103da610990565b61047c610477366004613870565b610996565b6040516103c99291906141dd565b6104926109ac565b6040516103c991906144b7565b6103bc6104ad366004613682565b6109b4565b6104c56104c036600461360c565b610a0c565b6040516103c991906143e8565b6103bc6104e0366004613870565b610a92565b6103bc610ad7565b6103da610b3f565b6103da610b45565b6103bc61050b366004613915565b610b4b565b6103da610ba0565b61052b61052636600461360c565b610baa565b005b61052b61053b3660046136cf565b610c3f565b6103da61054e36600461360c565b610c96565b61052b6105613660046137df565b610ca8565b610579610574366004613870565b610ee5565b6040516103c99190614404565b6103da610f27565b610596610f4b565b6040516103c99190614239565b6103da6105b13660046136ff565b610f5a565b6105c96105c436600461360c565b611011565b6040516103c995949392919061446b565b6103da6105e8366004613648565b611040565b6105f561105d565b6040516103c991906143f6565b6103da61061036600461360c565b61108d565b61052b6110ab565b6103da611119565b6103da61063336600461360c565b61111f565b6103bc610646366004613648565b611147565b610439611191565b6103bc6111a0565b6104116111b1565b6103bc610671366004613870565b61120c565b6103bc61068436600461360c565b611222565b6103bc6106973660046136cf565b61126d565b6104396112bf565b6103bc6106b236600461388e565b6112ce565b6103da61138e565b6103da611394565b61052b6106d53660046137c1565b61139a565b6103bc6106e836600461360c565b6113ec565b6103bc6106fb3660046136cf565b611402565b61052b61070e36600461360c565b611423565b61071b61174d565b6040516103c992919061444f565b6103bc610737366004613870565b611762565b6103da61074a366004613648565b611783565b6103da6117ae565b61076a610765366004613870565b6117b3565b6040516103c99392919061445d565b61052b61078736600461360c565b6117d4565b610596611801565b6103da6107a236600461360c565b611810565b60018054810190819055600090336107be81611840565b6001600160a01b0381166000908152600c60205260409020600101546107e59085906119e9565b600192505060015481146108145760405162461bcd60e51b815260040161080b906143c8565b60405180910390fd5b50919050565b670de0b6b3a764000081565b6001600160a01b0381166000908152600c602052604090205460608061084b83611b71565b9395909450915050565b6002805460408051602060018416156101000260001901909316849004601f810184900484028201840190925281815292918301828280156108d85780601f106108ad576101008083540402835291602001916108d8565b820191906000526020600020905b8154815290600101906020018083116108bb57829003601f168201915b505050505081565b336000818152600a602090815260408083206001600160a01b03871680855292528083208590555191929182907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259061093a90879061422b565b60405180910390a360019150505b92915050565b6006546001600160a01b03165b90565b6001600160a01b0381166000908152600c60205260409020600401545b919050565b600054600160a01b900460ff1681565b60055481565b6060806109a283611b71565b9094909350915050565b63ffffffff81565b600180548101908190556000906109ca85611840565b6109d633868686611cd3565b6109df84611840565b600191506001548114610a045760405162461bcd60e51b815260040161080b906143c8565b509392505050565b610a146132ab565b6001600160a01b0382166000908152600c6020908152604091829020805484526001810154918401919091526002810154918301919091526004810154606083015260058101546080830152610a6981611ff0565b60a0830152506001600160a01b0382166000908152600d602052604090205460c0820152919050565b60018054810190819055600090610aa93384612043565b610ab233611840565b6001915060015481146108145760405162461bcd60e51b815260040161080b906143c8565b6001805481019081905560009033610aee81611840565b6001600160a01b0381166000908152600c6020526040902060010154610b159082906119e9565b60019250506001548114610b3b5760405162461bcd60e51b815260040161080b906143c8565b5090565b60045481565b60001981565b60018054810190819055600090610b623384612043565b610b6b84612129565b610b7433611840565b600191506001548114610b995760405162461bcd60e51b815260040161080b906143c8565b5092915050565b600b546000190190565b610bb26111a0565b610bce5760405162461bcd60e51b815260040161080b90614358565b600054600160a01b900460ff161515600114610bfc5760405162461bcd60e51b815260040161080b906143a8565b610c0581612427565b7f34459cf4c63f38e9b4af4ff8f74035bad6157484e669ffde70188afdf9917c6881604051610c349190614171565b60405180910390a150565b610c476111a0565b610c635760405162461bcd60e51b815260040161080b90614358565b610c6c826124fa565b610c885760405162461bcd60e51b815260040161080b906142f8565b610c928282612043565b5050565b600d6020526000908152604090205481565b600054600160a01b900460ff1615610cd25760405162461bcd60e51b815260040161080b906142e8565b610cda612500565b600080546001600160a01b03191633179055600180558251610d039060029060208601906132e8565b508151610d179060039060208501906132e8565b506004818155670de0b6b3a7640000600955600680546001600160a01b0319166001600160a01b03878116919091179182905560408051636f307dc360e01b815290519290911692636f307dc3928282019260209290829003018186803b158015610d8157600080fd5b505afa158015610d95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610db9919081019061362a565b600780546001600160a01b03929092166001600160a01b031990921691909117905560408051600081830181815260608301845282528251818152602080820190945283830152600b8054600181018083559190925282518051919460029093027f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db90192610e4c92849290910190613362565b506020828101518051610e6592600185019201906133c3565b5050600080525050600e6020526000197fe710864318d4a32f37d6ce54cb3fadbef648dd12d8dbdf53973564d56b7f881c556006546009546040517faa54229fa6d6451d2cd5d13b5bc60f1230a0f79091118926e9b95d8f4811713a92610ed7926001600160a01b03909116916141c2565b60405180910390a150505050565b610eed61346e565b6000828152600e60209081526040909120805483526001810154918301919091526002810154610f1c90612515565b604083015250919050565b7fc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf790565b6006546001600160a01b031681565b60018054810190819055604080516020808802828101820190935287825260009392610fd492918a918a9182919085019084908082843760009201919091525050604080516020808b0282810182019093528a82529093508a9250899182918501908490808284376000920191909152506125b392505050565b91508215610fe657610fe63383612043565b60015481146110075760405162461bcd60e51b815260040161080b906143c8565b5095945050505050565b600c60205260009081526040902080546001820154600283015460048401546005909401549293919290919085565b600a60209081526000928352604080842090915290825290205481565b61106561348f565b60006110726008546127f4565b60408051808201909152600554815291016020820152905090565b6001600160a01b03166000908152600c602052604090206001015490565b6110b36111a0565b6110cf5760405162461bcd60e51b815260040161080b90614358565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b60085481565b6001600160a01b0381166000908152600c6020526040812061114081611ff0565b9392505050565b6001805481019081905560009061115d84611840565b6001600160a01b0384166000908152600c602052604090206001015461118890339086908690611cd3565b610b7483611840565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b6003805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156108d85780601f106108ad576101008083540402835291602001916108d8565b60018054810190819055600090610aa983612129565b600180548101908190556000903361123981611840565b6001600160a01b0381166000908152600c602052604090206001015461126490829081908790611cd3565b6107e584611840565b600180548101908190556000903361128481611840565b61129081828787611cd3565b61129985611840565b60019250506001548114610b995760405162461bcd60e51b815260040161080b906143c8565b6000546001600160a01b031681565b60018054810190819055604080516020808702828101820190935286825260009392849261134a9290918a918a91829185019084908082843760009201919091525050604080516020808b0282810182019093528a82529093508a9250899182918501908490808284376000920191909152506125b392505050565b90506113563382612043565b61135f88612129565b61136833611840565b600192505060015481146110075760405162461bcd60e51b815260040161080b906143c8565b60015481565b60095481565b6113e9816040518060400160405280600e81526020016d52656465656d61626c652044414960901b815250604051806040016040528060048152602001637244414960e01b8152506012610ca8565b50565b60018054810190819055600090610ab283611840565b600180548101908190556000903361141981611840565b61129985856119e9565b600180548101908190556114356111a0565b6114515760405162461bcd60e51b815260040161080b90614358565b60075460408051636f307dc360e01b8152905184926001600160a01b039081169290841691636f307dc391600480820192602092909190829003018186803b15801561149c57600080fd5b505afa1580156114b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506114d4919081019061362a565b6001600160a01b0316146114fa5760405162461bcd60e51b815260040161080b90614328565b600680546001600160a01b038381166001600160a01b031983161790925560055460405163852a12e360e01b81529290911691600091839163852a12e3916115449160040161422b565b602060405180830381600087803b15801561155e57600080fd5b505af1158015611572573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061159691908101906137a3565b60075460065460055460405163095ea7b360e01b81529394506001600160a01b039283169363095ea7b3936115d0931691906004016141c2565b602060405180830381600087803b1580156115ea57600080fd5b505af11580156115fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506116229190810190613785565b61163e5760405162461bcd60e51b815260040161080b906142d8565b600654600554604051630305da4f60e61b81526000926001600160a01b03169163c17693c091611671919060040161422b565b602060405180830381600087803b15801561168b57600080fd5b505af115801561169f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506116c391908101906137a3565b6009549091506116e9826116dd858463ffffffff61285316565b9063ffffffff61288d16565b60098190556040517faa54229fa6d6451d2cd5d13b5bc60f1230a0f79091118926e9b95d8f4811713a9161171f918a91906141c2565b60405180910390a150505050506001548114610c925760405162461bcd60e51b815260040161080b906143c8565b60085460009061175c816127f4565b91509091565b600180548101908190556000903361177981611840565b6107e581856119e9565b6001600160a01b039182166000908152600a6020908152604080832093909416825291909152205490565b603281565b600e6020526000908152604090208054600182015460029092015490919083565b6117dc6111a0565b6117f85760405162461bcd60e51b815260040161080b90614358565b6113e9816128cf565b6007546001600160a01b031681565b6001600160a01b0381166000908152600c602052604081206005810154829061183890612515565b949350505050565b6001600160a01b038082166000908152600c60209081526040808320600d8352818420600654835163a6afed9560e01b815293519296919591169363a6afed95936004808201949293918390030190829087803b1580156118a057600080fd5b505af11580156118b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506118d89190810190613785565b6118f45760405162461bcd60e51b815260040161080b90614258565b60006118ff83611ff0565b905080156119e3578154611919908263ffffffff61295016565b82556002830154611930908263ffffffff61295016565b6002840155600183015461194a908263ffffffff61295016565b6001840155600554611962908263ffffffff61295016565b6005556040516001600160a01b038516907f16cbc685358ca7d4e6b273dcdf2cb5d18c80b950aa2319b519756cd016233a6c906119a090849061422b565b60405180910390a2836001600160a01b031660006001600160a01b03166000805160206145d4833981519152836040516119da919061422b565b60405180910390a35b50505050565b336000908152600c6020526040902081611a155760405162461bcd60e51b815260040161080b90614378565b8060010154821115611a395760405162461bcd60e51b815260040161080b90614318565b6000611a453384612975565b6001830154909150611a5d908463ffffffff612a1216565b6001830181905560028301541115611a7a57600182015460028301555b600554611a8d908463ffffffff612a1216565b600555600854811015611aa857600880548290039055611aae565b60006008555b60075460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb90611ae090879087906004016141c2565b602060405180830381600087803b158015611afa57600080fd5b505af1158015611b0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611b329190810190613785565b611b4e5760405162461bcd60e51b815260040161080b90614338565b60405160009033906000805160206145d4833981519152906119da90879061422b565b6060808215801590611b8557506000198314155b15611cb457611b926134a9565b600b8481548110611b9f57fe5b906000526020600020906002020160405180604001604052908160008201805480602002602001604051908101604052809291908181526020018280548015611c1157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611bf3575b5050505050815260200160018201805480602002602001604051908101604052809291908181526020018280548015611c9557602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611c585790505b5050505050815250509050806000015192508060200151915050611cce565b505060408051600080825260208201908152818301909252905b915091565b816001600160a01b0316836001600160a01b03161415611d055760405162461bcd60e51b815260040161080b90614308565b6001600160a01b0383166000908152600c6020526040902060010154811115611d405760405162461bcd60e51b815260040161080b90614368565b60006001600160a01b038581169085161415611d5f5750600019611d87565b506001600160a01b038084166000908152600a60209081526040808320938816835292905220545b81811015611da75760405162461bcd60e51b815260040161080b90614268565b6000611db9828463ffffffff612a1216565b6001600160a01b0386166000908152600c602052604081206001015491925090611de9908563ffffffff612a1216565b6001600160a01b0386166000908152600c602052604081206001015491925090611e19908663ffffffff61295016565b6001600160a01b038088166000908152600c602052604080822054928b16825290205491925081149015801590611e6657506001600160a01b0387166000908152600c6020526040902054155b8015611e8c57506001600160a01b0388166000908152600c602052604090205460001914155b15611eb5576001600160a01b0388166000908152600c6020526040902054611eb5908890612043565b6001600160a01b038089166000908152600c60205260408082206001908101879055928a1682529020018290556000198514611f14576001600160a01b038089166000908152600a60209081526040808320938d168352929052208490555b80611f38576000611f258988612a54565b9050611f32888883612b04565b50611f5f565b6001600160a01b0388166000908152600c6020526040902054611f5f908990899089612d4b565b6001600160a01b0388166000908152600c6020526040902060018101546002909101541115611fac576001600160a01b0388166000908152600c6020526040902060018101546002909101555b866001600160a01b0316886001600160a01b03166000805160206145d483398151915288604051611fdd919061422b565b60405180910390a3505050505050505050565b6000806120008360050154612515565b905061201d8360020154846004015461295090919063ffffffff16565b811115612039578260020154836004015482030391505061097b565b600091505061097b565b6000198114806120545750600b5481105b6120705760405162461bcd60e51b815260040161080b906142a8565b6001600160a01b0382166000908152600c602090815260408083208054808552600e909352818420858552919093206001840154156120d65760006120b9878660010154612a54565b86865560018601549091506120d090889083612b04565b506120da565b8484555b815460001901825580546001018155604051859084906001600160a01b038916907f356f094000bcd3968ad51bf92c9d115ed7294626dea8ae4cc5b24273702e111390600090a4505050505050565b600754604051636eb1769f60e11b815282916001600160a01b03169063dd62ed3e9061215b903390309060040161417f565b60206040518083038186803b15801561217357600080fd5b505afa158015612187573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506121ab91908101906137a3565b10156121c95760405162461bcd60e51b815260040161080b90614388565b336000818152600c60205260409081902060075491516323b872dd60e01b815290926001600160a01b03909216916323b872dd9161220e91903090879060040161419a565b602060405180830381600087803b15801561222857600080fd5b505af115801561223c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506122609190810190613785565b61227c5760405162461bcd60e51b815260040161080b90614338565b60075460065460405163095ea7b360e01b81526001600160a01b039283169263095ea7b3926122b29291169086906004016141c2565b602060405180830381600087803b1580156122cc57600080fd5b505af11580156122e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506123049190810190613785565b6123205760405162461bcd60e51b815260040161080b906142d8565b600654604051630305da4f60e61b81526000916001600160a01b03169063c17693c09061235190869060040161422b565b602060405180830381600087803b15801561236b57600080fd5b505af115801561237f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506123a391908101906137a3565b6005549091506123b9908463ffffffff61295016565b60055560018201546123d1908463ffffffff61295016565b60018301556008546123e9908263ffffffff61295016565b60085560006123f782612e9e565b9050612404338583612b04565b60405133906000906000805160206145d4833981519152906119da90889061422b565b806001600160a01b03166352d1902d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561246057600080fd5b505afa158015612474573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061249891908101906137a3565b7fc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf7146124d65760405162461bcd60e51b815260040161080b90614278565b7fc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf755565b3b151590565b6000805460ff60a01b1916600160a01b179055565b60006109486009546116dd600660009054906101000a90046001600160a01b03166001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b15801561256e57600080fd5b505afa158015612582573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506125a691908101906137a3565b859063ffffffff61285316565b60008060008451116125d75760405162461bcd60e51b815260040161080b906143d8565b6032845111156125f95760405162461bcd60e51b815260040161080b90614398565b825184511461261a5760405162461bcd60e51b815260040161080b90614298565b506000805b84518210156126d057600084838151811061263657fe5b602002602001015163ffffffff16116126615760405162461bcd60e51b815260040161080b906143b8565b60006001600160a01b031685838151811061267857fe5b60200260200101516001600160a01b031614156126a75760405162461bcd60e51b815260040161080b906142c8565b8382815181106126b357fe5b602002602001015163ffffffff168101905081600101915061261f565b600091505b835182101561273a578063ffffffff80168584815181106126f257fe5b602002602001015163ffffffff16028161270857fe5b0484838151811061271557fe5b602002602001019063ffffffff16908163ffffffff16815250508160010191506126d5565b604080518082019091528581526020808201869052600b80546001818101808455600093909352845180519195939460029093027f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db901926127a092849290910190613362565b5060208281015180516127b992600185019201906133c3565b505050039250827f755babe5551737dcd4c723af196cff0ed1fa99a4c6957c62262d6b1425f864aa60405160405180910390a2505092915050565b6000610948670de0b6b3a76400006116dd600660009054906101000a90046001600160a01b03166001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b15801561256e57600080fd5b60008261286257506000610948565b8282028284828161286f57fe5b04146111405760405162461bcd60e51b815260040161080b90614348565b600061114083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612ec1565b6001600160a01b0381166128f55760405162461bcd60e51b815260040161080b90614288565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000828201838110156111405760405162461bcd60e51b815260040161080b906142b8565b60065460405163852a12e360e01b81526000916001600160a01b03169063852a12e3906129a690859060040161422b565b602060405180830381600087803b1580156129c057600080fd5b505af11580156129d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506129f891908101906137a3565b90506000612a0582612e9e565b9050610b99848483612ef8565b600061114083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506130ef565b6006546040805163a6afed9560e01b815290516000926001600160a01b03169163a6afed9591600480830192602092919082900301818787803b158015612a9a57600080fd5b505af1158015612aae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612ad29190810190613785565b612aee5760405162461bcd60e51b815260040161080b90614258565b612af78261311b565b9050610948838383612ef8565b6001600160a01b0383166000908152600c602052604081208054909190600b9060001914612b33578254612b36565b60005b81548110612b4057fe5b600091825260208220600290910201805490925015612cfc5750600084845b6001840154831015612cf5576000846000018481548110612b7c57fe5b60009182526020808320909101546001600160a01b0316808352600c9091526040822060018801549193509160001990910186149081612c095763ffffffff8016612bfc896001018981548110612bcf57fe5b600091825260209091206008820401548e916007166004026101000a900463ffffffff9081169061285316565b81612c0357fe5b04612c0b565b855b6001600160a01b038516600090815260038b016020526040902054909150612c39908263ffffffff61295016565b6001600160a01b038516600090815260038b0160205260409020556004830154612c69908263ffffffff61295016565b6004840155612c7886826131ba565b9550600082612ca75763ffffffff8016612c9a8a6001018a81548110612bcf57fe5b81612ca157fe5b04612ca9565b855b6005850154909150612cc1908263ffffffff61295016565b6005850155612cd086826131ba565b9550612ce58d868c60000154600186866131d5565b5050505050826001019250612b5f565b5050612d43565b6004830154612d11908663ffffffff61295016565b60048401556005830154612d2b908563ffffffff61295016565b60058401558254612d439087908190600189896131d5565b505050505050565b600660009054906101000a90046001600160a01b03166001600160a01b031663a6afed956040518163ffffffff1660e01b8152600401602060405180830381600087803b158015612d9b57600080fd5b505af1158015612daf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612dd39190810190613785565b612def5760405162461bcd60e51b815260040161080b90614258565b6001600160a01b038085166000908152600c60205260408082209286168252812090612e1a8461311b565b9050612e2a8360040154856131ba565b60048401556005830154612e3e90826131ba565b6005840155612e52878087600088866131d5565b6004820154612e67908563ffffffff61295016565b60048301556005820154612e81908263ffffffff61295016565b6005830155612e95868087600188866131d5565b50505050505050565b6000610948670de0b6b3a76400006116dd6009548561285390919063ffffffff16565b60008183612ee25760405162461bcd60e51b815260040161080b9190614247565b506000838581612eee57fe5b0495945050505050565b6001600160a01b0383166000908152600c602052604081208054909190600b9060001914612f27578254612f2a565b60005b81548110612f3457fe5b600091825260209091206002909102018054909150156130ae57838360005b60018401548110156130a6576000846000018281548110612f7057fe5b60009182526020808320909101546001600160a01b0316808352600c9091526040822060018801549193509160001990910184149081612fd05763ffffffff8016612fc3896001018781548110612bcf57fe5b81612fca57fe5b04612fd2565b865b9050612fe28360040154826131ba565b60048401556001600160a01b038416600090815260038a01602052604090205461300c90826131ba565b6001600160a01b038516600090815260038b01602052604090205561303187826131ba565b96506000826130605763ffffffff80166130538a6001018881548110612bcf57fe5b8161305a57fe5b04613062565b865b90506130728460050154826131ba565b600585015561308187826131ba565b96506130968d868c60000154600086866131d5565b5050505050806001019050612f53565b5050506130e8565b6130bc8260040154856131ba565b600483015560058201546130d090846131ba565b600583015581546130e89086908190600088886131d5565b5050505050565b600081848411156131135760405162461bcd60e51b815260040161080b9190614247565b505050900390565b6000610948600660009054906101000a90046001600160a01b03166001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b15801561316e57600080fd5b505afa158015613182573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506131a691908101906137a3565b6009546116dd90859063ffffffff61285316565b6000818310156131cc57506000610948565b50808203610948565b6000600e6000868152602001908152602001600020905084866001600160a01b0316886001600160a01b03167f7fb238306664f9cc50083b666d8979f411dd72154c6e9bf558c76b39e14e7d2987878760405161323493929190614210565b60405180910390a4831561327b576001810154613257908463ffffffff61295016565b60018201556002810154613271908363ffffffff61295016565b6002820155612e95565b6132898160010154846131ba565b6001820155600281015461329d90836131ba565b600282015550505050505050565b6040518060e00160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061332957805160ff1916838001178555613356565b82800160010185558215613356579182015b8281111561335657825182559160200191906001019061333b565b50610b3b9291506134c3565b8280548282559060005260206000209081019282156133b7579160200282015b828111156133b757825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190613382565b50610b3b9291506134dd565b828054828255906000526020600020906007016008900481019282156134625791602002820160005b8382111561343057835183826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026133ec565b80156134605782816101000a81549063ffffffff0219169055600401602081600301049283019260010302613430565b505b50610b3b929150613501565b60405180606001604052806000815260200160008152602001600081525090565b604051806040016040528060008152602001600081525090565b604051806040016040528060608152602001606081525090565b61095b91905b80821115610b3b57600081556001016134c9565b61095b91905b80821115610b3b5780546001600160a01b03191681556001016134e3565b61095b91905b80821115610b3b57805463ffffffff19168155600101613507565b8035610948816145a4565b8051610948816145a4565b60008083601f84011261354a57600080fd5b50813567ffffffffffffffff81111561356257600080fd5b60208301915083602082028301111561357a57600080fd5b9250929050565b8035610948816145b8565b8051610948816145b8565b8051610948816145c1565b8035610948816145ca565b600082601f8301126135be57600080fd5b81356135d16135cc826144ec565b6144c5565b915080825260208301602083018583830111156135ed57600080fd5b6135f8838284614562565b50505092915050565b8035610948816145c1565b60006020828403121561361e57600080fd5b60006118388484613522565b60006020828403121561363c57600080fd5b6000611838848461352d565b6000806040838503121561365b57600080fd5b60006136678585613522565b925050602061367885828601613522565b9150509250929050565b60008060006060848603121561369757600080fd5b60006136a38686613522565b93505060206136b486828701613522565b92505060406136c586828701613601565b9150509250925092565b600080604083850312156136e257600080fd5b60006136ee8585613522565b925050602061367885828601613601565b60008060008060006060868803121561371757600080fd5b853567ffffffffffffffff81111561372e57600080fd5b61373a88828901613538565b9550955050602086013567ffffffffffffffff81111561375957600080fd5b61376588828901613538565b9350935050604061377888828901613581565b9150509295509295909350565b60006020828403121561379757600080fd5b6000611838848461358c565b6000602082840312156137b557600080fd5b60006118388484613597565b6000602082840312156137d357600080fd5b600061183884846135a2565b600080600080608085870312156137f557600080fd5b600061380187876135a2565b945050602085013567ffffffffffffffff81111561381e57600080fd5b61382a878288016135ad565b935050604085013567ffffffffffffffff81111561384757600080fd5b613853878288016135ad565b925050606061386487828801613601565b91505092959194509250565b60006020828403121561388257600080fd5b60006118388484613601565b6000806000806000606086880312156138a657600080fd5b60006138b28888613601565b955050602086013567ffffffffffffffff8111156138cf57600080fd5b6138db88828901613538565b9450945050604086013567ffffffffffffffff8111156138fa57600080fd5b61390688828901613538565b92509250509295509295909350565b6000806040838503121561392857600080fd5b60006136ee8585613601565b60006139408383613963565b505060200190565b60006139408383614168565b61395d81614557565b82525050565b61395d81614527565b60006139778261451a565b613981818561451e565b935061398c83614514565b8060005b838110156139ba5781516139a48882613934565b97506139af83614514565b925050600101613990565b509495945050505050565b60006139d08261451a565b6139da818561451e565b93506139e583614514565b8060005b838110156139ba5781516139fd8882613948565b9750613a0883614514565b9250506001016139e9565b61395d81614532565b61395d8161095b565b61395d81614537565b6000613a398261451a565b613a43818561451e565b9350613a5381856020860161456e565b613a5c8161459a565b9093019392505050565b6000613a7360158361451e565b741858d8dc9d59525b9d195c995cdd0819985a5b1959605a1b815260200192915050565b6000613aa460218361451e565b7f4e6f7420656e6f75676820616c6c6f77616e636520666f72207472616e7366658152603960f91b602082015260400192915050565b6000613ae7600e8361451e565b6d4e6f7420636f6d70617469626c6560901b815260200192915050565b6000613b1160268361451e565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b602082015260400192915050565b6000613b5960208361451e565b7f496e76616c6964206861743a206c656e677468206e6f74206d61746368696e67815260200192915050565b6000613b92600e8361451e565b6d125b9d985b1a59081a185d08125160921b815260200192915050565b6000613bbc601b8361451e565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b6000613bf560288361451e565b7f496e76616c6964206861743a20726563697069656e742073686f756c64206e6f815267074206265203078360c41b602082015260400192915050565b6000613c3f60148361451e565b731d1bdad95b88185c1c1c9bdd994819985a5b195960621b815260200192915050565b6000613c6f60298361451e565b7f546865206c6962726172792068617320616c7265616479206265656e20696e698152683a34b0b634bd32b21760b91b602082015260400192915050565b6000613cba602e8361451e565b7f41646d696e2063616e206f6e6c79206368616e67652068617420666f7220636f81526d6e7472616374206164647265737360901b602082015260400192915050565b6000613d0a60188361451e565b7f7372632073686f756c64206e6f7420657175616c206473740000000000000000815260200192915050565b6000613d43601c8361451e565b7f4e6f7420656e6f7567682062616c616e636520746f2072656465656d00000000815260200192915050565b6000613d7c60328361451e565b7f4e65772073747261746567792073686f756c642068617665207468652073616d81527119481d5b99195c9b1e5a5b99c8185cdcd95d60721b602082015260400192915050565b6000613dd060158361451e565b741d1bdad95b881d1c985b9cd9995c8819985a5b1959605a1b815260200192915050565b6000613e0160218361451e565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b6000613e4460208361451e565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572815260200192915050565b6000613e7d601e8361451e565b7f4e6f7420656e6f7567682062616c616e636520746f207472616e736665720000815260200192915050565b6000613eb6601c8361451e565b7f52656465656d20616d6f756e742063616e6e6f74206265207a65726f00000000815260200192915050565b6000613eef60148361451e565b734e6f7420656e6f75676820616c6c6f77616e636560601b815260200192915050565b6000613f1f60328361451e565b7f496e76616c696c64206861743a206d6178696d756d206e756d626572206f66208152711c9958da5c1a595b9d1cc81c995858da195960721b602082015260400192915050565b6000613f7360338361451e565b7f546865206c696272617279206973206c6f636b65642e204e6f206469726563748152721013b1b0b636139034b99030b63637bbb2b21760691b602082015260400192915050565b6000613fc8602f8361451e565b7f496e76616c6964206861743a2070726f706f7274696f6e2073686f756c64206281526e065206c6172676572207468616e203608c1b602082015260400192915050565b6000614019601f8361451e565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00815260200192915050565b600061405260238361451e565b7f496e76616c6964206861743a206174206c65617374206f6e6520726563697069815262195b9d60ea1b602082015260400192915050565b805160e083019061409b8482613a1c565b5060208201516140ae6020850182613a1c565b5060408201516140c16040850182613a1c565b5060608201516140d46060850182613a1c565b5060808201516140e76080850182613a1c565b5060a08201516140fa60a0850182613a1c565b5060c08201516119e360c0850182613a1c565b8051604083019061411e8482613a1c565b5060208201516119e36020850182613a1c565b805160608301906141428482613a1c565b5060208201516141556020850182613a1c565b5060408201516119e36040850182613a1c565b61395d8161454e565b602081016109488284613963565b6040810161418d8285613954565b6111406020830184613963565b606081016141a88286613954565b6141b56020830185613963565b6118386040830184613a1c565b604081016141d08285613963565b6111406020830184613a1c565b604080825281016141ee818561396c565b9050818103602083015261183881846139c5565b602081016109488284613a13565b6060810161421e8286613a13565b6141b56020830185613a1c565b602081016109488284613a1c565b602081016109488284613a25565b602080825281016111408184613a2e565b6020808252810161094881613a66565b6020808252810161094881613a97565b6020808252810161094881613ada565b6020808252810161094881613b04565b6020808252810161094881613b4c565b6020808252810161094881613b85565b6020808252810161094881613baf565b6020808252810161094881613be8565b6020808252810161094881613c32565b6020808252810161094881613c62565b6020808252810161094881613cad565b6020808252810161094881613cfd565b6020808252810161094881613d36565b6020808252810161094881613d6f565b6020808252810161094881613dc3565b6020808252810161094881613df4565b6020808252810161094881613e37565b6020808252810161094881613e70565b6020808252810161094881613ea9565b6020808252810161094881613ee2565b6020808252810161094881613f12565b6020808252810161094881613f66565b6020808252810161094881613fbb565b602080825281016109488161400c565b6020808252810161094881614045565b60e08101610948828461408a565b60408101610948828461410d565b606081016109488284614131565b606081016144208286613a1c565b8181036020830152614432818561396c565b9050818103604083015261444681846139c5565b95945050505050565b604081016141d08285613a1c565b6060810161421e8286613a1c565b60a081016144798288613a1c565b6144866020830187613a1c565b6144936040830186613a1c565b6144a06060830185613a1c565b6144ad6080830184613a1c565b9695505050505050565b602081016109488284614168565b60405181810167ffffffffffffffff811182821017156144e457600080fd5b604052919050565b600067ffffffffffffffff82111561450357600080fd5b506020601f91909101601f19160190565b60200190565b5190565b90815260200190565b600061094882614542565b151590565b600061094882614527565b6001600160a01b031690565b63ffffffff1690565b600061094882614537565b82818337506000910152565b60005b83811015614589578181015183820152602001614571565b838111156119e35750506000910152565b601f01601f191690565b6145ad81614527565b81146113e957600080fd5b6145ad81614532565b6145ad8161095b565b6145ad8161453756feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa365627a7a72315820966b6f4dc2e27d4ba6b4de3a87038d644cddfec7d29f0dbf0e9342dd9cf74d9b6c6578706572696d656e74616cf564736f6c634300050c0040

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106103a45760003560e01c806370a08231116101e9578063c034d0db1161010f578063d8884795116100ad578063f04bf8b31161007c578063f04bf8b314610757578063f2fde38b14610779578063fc0c546a1461078c578063fdbbf8ac14610794576103a4565b8063d888479514610713578063db006a7514610729578063dd62ed3e1461073c578063e192782b1461074f576103a4565b8063c4d66de8116100e9578063c4d66de8146106c7578063d007c644146106da578063d271be3f146106ed578063d3ac25c414610700576103a4565b8063c034d0db146104f5578063c1a2007d14610431578063c200659e146106bf576103a4565b80638f32d59b11610187578063a9059cbb11610156578063a9059cbb14610689578063b2bdfa7b1461069c578063b5dbfc1a146106a4578063bf5bfdfb146106b7576103a4565b80638f32d59b1461065357806395d89b411461065b578063a0712d6814610663578063a3a7e7f314610676576103a4565b806377ede051116101c357806377ede0511461062557806381c8d895146103d257806384d4b410146106385780638da5cb5b1461064b576103a4565b806370a0823114610602578063715018a61461061557806371ee46eb1461061d576103a4565b8063313ce567116102ce5780634d12d4b61161026c5780635cde50551161023b5780635cde5055146105a35780635e5c06e2146105b657806363152a50146105da5780636b4169c3146105ed576103a4565b80634d12d4b6146105535780634fd7c0dd1461056657806352d1902d14610586578063556043ef1461058e576103a4565b80633e20a929116102a85780633e20a9291461051057806346951954146105185780634929fbf71461052d578063496cc16414610540576103a4565b8063313ce567146104ed57806333a581d2146104f5578063388c0b8c146104fd576103a4565b8063158ef93e1161034657806323b872dd1161031557806323b872dd1461049f57806328cdfaeb146104b25780632f2ba814146104d25780632f4350c2146104e5576103a4565b8063158ef93e1461045957806318160ddd146104615780631cda95d514610469578063226e835c1461048a576103a4565b806306fdde031161038257806306fdde0314610409578063095ea7b31461041e57806310f3a6d81461043157806313e23e4114610446576103a4565b80630290cbc8146103a9578063039ab887146103d2578063054ab01a146103e7575b600080fd5b6103bc6103b736600461360c565b6107a7565b6040516103c99190614202565b60405180910390f35b6103da61081a565b6040516103c9919061422b565b6103fa6103f536600461360c565b610826565b6040516103c993929190614412565b610411610855565b6040516103c99190614247565b6103bc61042c3660046136cf565b6108e0565b61043961094e565b6040516103c99190614171565b6103da61045436600461360c565b61095e565b6103bc610980565b6103da610990565b61047c610477366004613870565b610996565b6040516103c99291906141dd565b6104926109ac565b6040516103c991906144b7565b6103bc6104ad366004613682565b6109b4565b6104c56104c036600461360c565b610a0c565b6040516103c991906143e8565b6103bc6104e0366004613870565b610a92565b6103bc610ad7565b6103da610b3f565b6103da610b45565b6103bc61050b366004613915565b610b4b565b6103da610ba0565b61052b61052636600461360c565b610baa565b005b61052b61053b3660046136cf565b610c3f565b6103da61054e36600461360c565b610c96565b61052b6105613660046137df565b610ca8565b610579610574366004613870565b610ee5565b6040516103c99190614404565b6103da610f27565b610596610f4b565b6040516103c99190614239565b6103da6105b13660046136ff565b610f5a565b6105c96105c436600461360c565b611011565b6040516103c995949392919061446b565b6103da6105e8366004613648565b611040565b6105f561105d565b6040516103c991906143f6565b6103da61061036600461360c565b61108d565b61052b6110ab565b6103da611119565b6103da61063336600461360c565b61111f565b6103bc610646366004613648565b611147565b610439611191565b6103bc6111a0565b6104116111b1565b6103bc610671366004613870565b61120c565b6103bc61068436600461360c565b611222565b6103bc6106973660046136cf565b61126d565b6104396112bf565b6103bc6106b236600461388e565b6112ce565b6103da61138e565b6103da611394565b61052b6106d53660046137c1565b61139a565b6103bc6106e836600461360c565b6113ec565b6103bc6106fb3660046136cf565b611402565b61052b61070e36600461360c565b611423565b61071b61174d565b6040516103c992919061444f565b6103bc610737366004613870565b611762565b6103da61074a366004613648565b611783565b6103da6117ae565b61076a610765366004613870565b6117b3565b6040516103c99392919061445d565b61052b61078736600461360c565b6117d4565b610596611801565b6103da6107a236600461360c565b611810565b60018054810190819055600090336107be81611840565b6001600160a01b0381166000908152600c60205260409020600101546107e59085906119e9565b600192505060015481146108145760405162461bcd60e51b815260040161080b906143c8565b60405180910390fd5b50919050565b670de0b6b3a764000081565b6001600160a01b0381166000908152600c602052604090205460608061084b83611b71565b9395909450915050565b6002805460408051602060018416156101000260001901909316849004601f810184900484028201840190925281815292918301828280156108d85780601f106108ad576101008083540402835291602001916108d8565b820191906000526020600020905b8154815290600101906020018083116108bb57829003601f168201915b505050505081565b336000818152600a602090815260408083206001600160a01b03871680855292528083208590555191929182907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259061093a90879061422b565b60405180910390a360019150505b92915050565b6006546001600160a01b03165b90565b6001600160a01b0381166000908152600c60205260409020600401545b919050565b600054600160a01b900460ff1681565b60055481565b6060806109a283611b71565b9094909350915050565b63ffffffff81565b600180548101908190556000906109ca85611840565b6109d633868686611cd3565b6109df84611840565b600191506001548114610a045760405162461bcd60e51b815260040161080b906143c8565b509392505050565b610a146132ab565b6001600160a01b0382166000908152600c6020908152604091829020805484526001810154918401919091526002810154918301919091526004810154606083015260058101546080830152610a6981611ff0565b60a0830152506001600160a01b0382166000908152600d602052604090205460c0820152919050565b60018054810190819055600090610aa93384612043565b610ab233611840565b6001915060015481146108145760405162461bcd60e51b815260040161080b906143c8565b6001805481019081905560009033610aee81611840565b6001600160a01b0381166000908152600c6020526040902060010154610b159082906119e9565b60019250506001548114610b3b5760405162461bcd60e51b815260040161080b906143c8565b5090565b60045481565b60001981565b60018054810190819055600090610b623384612043565b610b6b84612129565b610b7433611840565b600191506001548114610b995760405162461bcd60e51b815260040161080b906143c8565b5092915050565b600b546000190190565b610bb26111a0565b610bce5760405162461bcd60e51b815260040161080b90614358565b600054600160a01b900460ff161515600114610bfc5760405162461bcd60e51b815260040161080b906143a8565b610c0581612427565b7f34459cf4c63f38e9b4af4ff8f74035bad6157484e669ffde70188afdf9917c6881604051610c349190614171565b60405180910390a150565b610c476111a0565b610c635760405162461bcd60e51b815260040161080b90614358565b610c6c826124fa565b610c885760405162461bcd60e51b815260040161080b906142f8565b610c928282612043565b5050565b600d6020526000908152604090205481565b600054600160a01b900460ff1615610cd25760405162461bcd60e51b815260040161080b906142e8565b610cda612500565b600080546001600160a01b03191633179055600180558251610d039060029060208601906132e8565b508151610d179060039060208501906132e8565b506004818155670de0b6b3a7640000600955600680546001600160a01b0319166001600160a01b03878116919091179182905560408051636f307dc360e01b815290519290911692636f307dc3928282019260209290829003018186803b158015610d8157600080fd5b505afa158015610d95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610db9919081019061362a565b600780546001600160a01b03929092166001600160a01b031990921691909117905560408051600081830181815260608301845282528251818152602080820190945283830152600b8054600181018083559190925282518051919460029093027f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db90192610e4c92849290910190613362565b506020828101518051610e6592600185019201906133c3565b5050600080525050600e6020526000197fe710864318d4a32f37d6ce54cb3fadbef648dd12d8dbdf53973564d56b7f881c556006546009546040517faa54229fa6d6451d2cd5d13b5bc60f1230a0f79091118926e9b95d8f4811713a92610ed7926001600160a01b03909116916141c2565b60405180910390a150505050565b610eed61346e565b6000828152600e60209081526040909120805483526001810154918301919091526002810154610f1c90612515565b604083015250919050565b7fc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf790565b6006546001600160a01b031681565b60018054810190819055604080516020808802828101820190935287825260009392610fd492918a918a9182919085019084908082843760009201919091525050604080516020808b0282810182019093528a82529093508a9250899182918501908490808284376000920191909152506125b392505050565b91508215610fe657610fe63383612043565b60015481146110075760405162461bcd60e51b815260040161080b906143c8565b5095945050505050565b600c60205260009081526040902080546001820154600283015460048401546005909401549293919290919085565b600a60209081526000928352604080842090915290825290205481565b61106561348f565b60006110726008546127f4565b60408051808201909152600554815291016020820152905090565b6001600160a01b03166000908152600c602052604090206001015490565b6110b36111a0565b6110cf5760405162461bcd60e51b815260040161080b90614358565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b60085481565b6001600160a01b0381166000908152600c6020526040812061114081611ff0565b9392505050565b6001805481019081905560009061115d84611840565b6001600160a01b0384166000908152600c602052604090206001015461118890339086908690611cd3565b610b7483611840565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b6003805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156108d85780601f106108ad576101008083540402835291602001916108d8565b60018054810190819055600090610aa983612129565b600180548101908190556000903361123981611840565b6001600160a01b0381166000908152600c602052604090206001015461126490829081908790611cd3565b6107e584611840565b600180548101908190556000903361128481611840565b61129081828787611cd3565b61129985611840565b60019250506001548114610b995760405162461bcd60e51b815260040161080b906143c8565b6000546001600160a01b031681565b60018054810190819055604080516020808702828101820190935286825260009392849261134a9290918a918a91829185019084908082843760009201919091525050604080516020808b0282810182019093528a82529093508a9250899182918501908490808284376000920191909152506125b392505050565b90506113563382612043565b61135f88612129565b61136833611840565b600192505060015481146110075760405162461bcd60e51b815260040161080b906143c8565b60015481565b60095481565b6113e9816040518060400160405280600e81526020016d52656465656d61626c652044414960901b815250604051806040016040528060048152602001637244414960e01b8152506012610ca8565b50565b60018054810190819055600090610ab283611840565b600180548101908190556000903361141981611840565b61129985856119e9565b600180548101908190556114356111a0565b6114515760405162461bcd60e51b815260040161080b90614358565b60075460408051636f307dc360e01b8152905184926001600160a01b039081169290841691636f307dc391600480820192602092909190829003018186803b15801561149c57600080fd5b505afa1580156114b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506114d4919081019061362a565b6001600160a01b0316146114fa5760405162461bcd60e51b815260040161080b90614328565b600680546001600160a01b038381166001600160a01b031983161790925560055460405163852a12e360e01b81529290911691600091839163852a12e3916115449160040161422b565b602060405180830381600087803b15801561155e57600080fd5b505af1158015611572573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061159691908101906137a3565b60075460065460055460405163095ea7b360e01b81529394506001600160a01b039283169363095ea7b3936115d0931691906004016141c2565b602060405180830381600087803b1580156115ea57600080fd5b505af11580156115fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506116229190810190613785565b61163e5760405162461bcd60e51b815260040161080b906142d8565b600654600554604051630305da4f60e61b81526000926001600160a01b03169163c17693c091611671919060040161422b565b602060405180830381600087803b15801561168b57600080fd5b505af115801561169f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506116c391908101906137a3565b6009549091506116e9826116dd858463ffffffff61285316565b9063ffffffff61288d16565b60098190556040517faa54229fa6d6451d2cd5d13b5bc60f1230a0f79091118926e9b95d8f4811713a9161171f918a91906141c2565b60405180910390a150505050506001548114610c925760405162461bcd60e51b815260040161080b906143c8565b60085460009061175c816127f4565b91509091565b600180548101908190556000903361177981611840565b6107e581856119e9565b6001600160a01b039182166000908152600a6020908152604080832093909416825291909152205490565b603281565b600e6020526000908152604090208054600182015460029092015490919083565b6117dc6111a0565b6117f85760405162461bcd60e51b815260040161080b90614358565b6113e9816128cf565b6007546001600160a01b031681565b6001600160a01b0381166000908152600c602052604081206005810154829061183890612515565b949350505050565b6001600160a01b038082166000908152600c60209081526040808320600d8352818420600654835163a6afed9560e01b815293519296919591169363a6afed95936004808201949293918390030190829087803b1580156118a057600080fd5b505af11580156118b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506118d89190810190613785565b6118f45760405162461bcd60e51b815260040161080b90614258565b60006118ff83611ff0565b905080156119e3578154611919908263ffffffff61295016565b82556002830154611930908263ffffffff61295016565b6002840155600183015461194a908263ffffffff61295016565b6001840155600554611962908263ffffffff61295016565b6005556040516001600160a01b038516907f16cbc685358ca7d4e6b273dcdf2cb5d18c80b950aa2319b519756cd016233a6c906119a090849061422b565b60405180910390a2836001600160a01b031660006001600160a01b03166000805160206145d4833981519152836040516119da919061422b565b60405180910390a35b50505050565b336000908152600c6020526040902081611a155760405162461bcd60e51b815260040161080b90614378565b8060010154821115611a395760405162461bcd60e51b815260040161080b90614318565b6000611a453384612975565b6001830154909150611a5d908463ffffffff612a1216565b6001830181905560028301541115611a7a57600182015460028301555b600554611a8d908463ffffffff612a1216565b600555600854811015611aa857600880548290039055611aae565b60006008555b60075460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb90611ae090879087906004016141c2565b602060405180830381600087803b158015611afa57600080fd5b505af1158015611b0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611b329190810190613785565b611b4e5760405162461bcd60e51b815260040161080b90614338565b60405160009033906000805160206145d4833981519152906119da90879061422b565b6060808215801590611b8557506000198314155b15611cb457611b926134a9565b600b8481548110611b9f57fe5b906000526020600020906002020160405180604001604052908160008201805480602002602001604051908101604052809291908181526020018280548015611c1157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611bf3575b5050505050815260200160018201805480602002602001604051908101604052809291908181526020018280548015611c9557602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611c585790505b5050505050815250509050806000015192508060200151915050611cce565b505060408051600080825260208201908152818301909252905b915091565b816001600160a01b0316836001600160a01b03161415611d055760405162461bcd60e51b815260040161080b90614308565b6001600160a01b0383166000908152600c6020526040902060010154811115611d405760405162461bcd60e51b815260040161080b90614368565b60006001600160a01b038581169085161415611d5f5750600019611d87565b506001600160a01b038084166000908152600a60209081526040808320938816835292905220545b81811015611da75760405162461bcd60e51b815260040161080b90614268565b6000611db9828463ffffffff612a1216565b6001600160a01b0386166000908152600c602052604081206001015491925090611de9908563ffffffff612a1216565b6001600160a01b0386166000908152600c602052604081206001015491925090611e19908663ffffffff61295016565b6001600160a01b038088166000908152600c602052604080822054928b16825290205491925081149015801590611e6657506001600160a01b0387166000908152600c6020526040902054155b8015611e8c57506001600160a01b0388166000908152600c602052604090205460001914155b15611eb5576001600160a01b0388166000908152600c6020526040902054611eb5908890612043565b6001600160a01b038089166000908152600c60205260408082206001908101879055928a1682529020018290556000198514611f14576001600160a01b038089166000908152600a60209081526040808320938d168352929052208490555b80611f38576000611f258988612a54565b9050611f32888883612b04565b50611f5f565b6001600160a01b0388166000908152600c6020526040902054611f5f908990899089612d4b565b6001600160a01b0388166000908152600c6020526040902060018101546002909101541115611fac576001600160a01b0388166000908152600c6020526040902060018101546002909101555b866001600160a01b0316886001600160a01b03166000805160206145d483398151915288604051611fdd919061422b565b60405180910390a3505050505050505050565b6000806120008360050154612515565b905061201d8360020154846004015461295090919063ffffffff16565b811115612039578260020154836004015482030391505061097b565b600091505061097b565b6000198114806120545750600b5481105b6120705760405162461bcd60e51b815260040161080b906142a8565b6001600160a01b0382166000908152600c602090815260408083208054808552600e909352818420858552919093206001840154156120d65760006120b9878660010154612a54565b86865560018601549091506120d090889083612b04565b506120da565b8484555b815460001901825580546001018155604051859084906001600160a01b038916907f356f094000bcd3968ad51bf92c9d115ed7294626dea8ae4cc5b24273702e111390600090a4505050505050565b600754604051636eb1769f60e11b815282916001600160a01b03169063dd62ed3e9061215b903390309060040161417f565b60206040518083038186803b15801561217357600080fd5b505afa158015612187573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506121ab91908101906137a3565b10156121c95760405162461bcd60e51b815260040161080b90614388565b336000818152600c60205260409081902060075491516323b872dd60e01b815290926001600160a01b03909216916323b872dd9161220e91903090879060040161419a565b602060405180830381600087803b15801561222857600080fd5b505af115801561223c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506122609190810190613785565b61227c5760405162461bcd60e51b815260040161080b90614338565b60075460065460405163095ea7b360e01b81526001600160a01b039283169263095ea7b3926122b29291169086906004016141c2565b602060405180830381600087803b1580156122cc57600080fd5b505af11580156122e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506123049190810190613785565b6123205760405162461bcd60e51b815260040161080b906142d8565b600654604051630305da4f60e61b81526000916001600160a01b03169063c17693c09061235190869060040161422b565b602060405180830381600087803b15801561236b57600080fd5b505af115801561237f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506123a391908101906137a3565b6005549091506123b9908463ffffffff61295016565b60055560018201546123d1908463ffffffff61295016565b60018301556008546123e9908263ffffffff61295016565b60085560006123f782612e9e565b9050612404338583612b04565b60405133906000906000805160206145d4833981519152906119da90889061422b565b806001600160a01b03166352d1902d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561246057600080fd5b505afa158015612474573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061249891908101906137a3565b7fc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf7146124d65760405162461bcd60e51b815260040161080b90614278565b7fc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf755565b3b151590565b6000805460ff60a01b1916600160a01b179055565b60006109486009546116dd600660009054906101000a90046001600160a01b03166001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b15801561256e57600080fd5b505afa158015612582573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506125a691908101906137a3565b859063ffffffff61285316565b60008060008451116125d75760405162461bcd60e51b815260040161080b906143d8565b6032845111156125f95760405162461bcd60e51b815260040161080b90614398565b825184511461261a5760405162461bcd60e51b815260040161080b90614298565b506000805b84518210156126d057600084838151811061263657fe5b602002602001015163ffffffff16116126615760405162461bcd60e51b815260040161080b906143b8565b60006001600160a01b031685838151811061267857fe5b60200260200101516001600160a01b031614156126a75760405162461bcd60e51b815260040161080b906142c8565b8382815181106126b357fe5b602002602001015163ffffffff168101905081600101915061261f565b600091505b835182101561273a578063ffffffff80168584815181106126f257fe5b602002602001015163ffffffff16028161270857fe5b0484838151811061271557fe5b602002602001019063ffffffff16908163ffffffff16815250508160010191506126d5565b604080518082019091528581526020808201869052600b80546001818101808455600093909352845180519195939460029093027f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db901926127a092849290910190613362565b5060208281015180516127b992600185019201906133c3565b505050039250827f755babe5551737dcd4c723af196cff0ed1fa99a4c6957c62262d6b1425f864aa60405160405180910390a2505092915050565b6000610948670de0b6b3a76400006116dd600660009054906101000a90046001600160a01b03166001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b15801561256e57600080fd5b60008261286257506000610948565b8282028284828161286f57fe5b04146111405760405162461bcd60e51b815260040161080b90614348565b600061114083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612ec1565b6001600160a01b0381166128f55760405162461bcd60e51b815260040161080b90614288565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000828201838110156111405760405162461bcd60e51b815260040161080b906142b8565b60065460405163852a12e360e01b81526000916001600160a01b03169063852a12e3906129a690859060040161422b565b602060405180830381600087803b1580156129c057600080fd5b505af11580156129d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506129f891908101906137a3565b90506000612a0582612e9e565b9050610b99848483612ef8565b600061114083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506130ef565b6006546040805163a6afed9560e01b815290516000926001600160a01b03169163a6afed9591600480830192602092919082900301818787803b158015612a9a57600080fd5b505af1158015612aae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612ad29190810190613785565b612aee5760405162461bcd60e51b815260040161080b90614258565b612af78261311b565b9050610948838383612ef8565b6001600160a01b0383166000908152600c602052604081208054909190600b9060001914612b33578254612b36565b60005b81548110612b4057fe5b600091825260208220600290910201805490925015612cfc5750600084845b6001840154831015612cf5576000846000018481548110612b7c57fe5b60009182526020808320909101546001600160a01b0316808352600c9091526040822060018801549193509160001990910186149081612c095763ffffffff8016612bfc896001018981548110612bcf57fe5b600091825260209091206008820401548e916007166004026101000a900463ffffffff9081169061285316565b81612c0357fe5b04612c0b565b855b6001600160a01b038516600090815260038b016020526040902054909150612c39908263ffffffff61295016565b6001600160a01b038516600090815260038b0160205260409020556004830154612c69908263ffffffff61295016565b6004840155612c7886826131ba565b9550600082612ca75763ffffffff8016612c9a8a6001018a81548110612bcf57fe5b81612ca157fe5b04612ca9565b855b6005850154909150612cc1908263ffffffff61295016565b6005850155612cd086826131ba565b9550612ce58d868c60000154600186866131d5565b5050505050826001019250612b5f565b5050612d43565b6004830154612d11908663ffffffff61295016565b60048401556005830154612d2b908563ffffffff61295016565b60058401558254612d439087908190600189896131d5565b505050505050565b600660009054906101000a90046001600160a01b03166001600160a01b031663a6afed956040518163ffffffff1660e01b8152600401602060405180830381600087803b158015612d9b57600080fd5b505af1158015612daf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612dd39190810190613785565b612def5760405162461bcd60e51b815260040161080b90614258565b6001600160a01b038085166000908152600c60205260408082209286168252812090612e1a8461311b565b9050612e2a8360040154856131ba565b60048401556005830154612e3e90826131ba565b6005840155612e52878087600088866131d5565b6004820154612e67908563ffffffff61295016565b60048301556005820154612e81908263ffffffff61295016565b6005830155612e95868087600188866131d5565b50505050505050565b6000610948670de0b6b3a76400006116dd6009548561285390919063ffffffff16565b60008183612ee25760405162461bcd60e51b815260040161080b9190614247565b506000838581612eee57fe5b0495945050505050565b6001600160a01b0383166000908152600c602052604081208054909190600b9060001914612f27578254612f2a565b60005b81548110612f3457fe5b600091825260209091206002909102018054909150156130ae57838360005b60018401548110156130a6576000846000018281548110612f7057fe5b60009182526020808320909101546001600160a01b0316808352600c9091526040822060018801549193509160001990910184149081612fd05763ffffffff8016612fc3896001018781548110612bcf57fe5b81612fca57fe5b04612fd2565b865b9050612fe28360040154826131ba565b60048401556001600160a01b038416600090815260038a01602052604090205461300c90826131ba565b6001600160a01b038516600090815260038b01602052604090205561303187826131ba565b96506000826130605763ffffffff80166130538a6001018881548110612bcf57fe5b8161305a57fe5b04613062565b865b90506130728460050154826131ba565b600585015561308187826131ba565b96506130968d868c60000154600086866131d5565b5050505050806001019050612f53565b5050506130e8565b6130bc8260040154856131ba565b600483015560058201546130d090846131ba565b600583015581546130e89086908190600088886131d5565b5050505050565b600081848411156131135760405162461bcd60e51b815260040161080b9190614247565b505050900390565b6000610948600660009054906101000a90046001600160a01b03166001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b15801561316e57600080fd5b505afa158015613182573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506131a691908101906137a3565b6009546116dd90859063ffffffff61285316565b6000818310156131cc57506000610948565b50808203610948565b6000600e6000868152602001908152602001600020905084866001600160a01b0316886001600160a01b03167f7fb238306664f9cc50083b666d8979f411dd72154c6e9bf558c76b39e14e7d2987878760405161323493929190614210565b60405180910390a4831561327b576001810154613257908463ffffffff61295016565b60018201556002810154613271908363ffffffff61295016565b6002820155612e95565b6132898160010154846131ba565b6001820155600281015461329d90836131ba565b600282015550505050505050565b6040518060e00160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061332957805160ff1916838001178555613356565b82800160010185558215613356579182015b8281111561335657825182559160200191906001019061333b565b50610b3b9291506134c3565b8280548282559060005260206000209081019282156133b7579160200282015b828111156133b757825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190613382565b50610b3b9291506134dd565b828054828255906000526020600020906007016008900481019282156134625791602002820160005b8382111561343057835183826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026133ec565b80156134605782816101000a81549063ffffffff0219169055600401602081600301049283019260010302613430565b505b50610b3b929150613501565b60405180606001604052806000815260200160008152602001600081525090565b604051806040016040528060008152602001600081525090565b604051806040016040528060608152602001606081525090565b61095b91905b80821115610b3b57600081556001016134c9565b61095b91905b80821115610b3b5780546001600160a01b03191681556001016134e3565b61095b91905b80821115610b3b57805463ffffffff19168155600101613507565b8035610948816145a4565b8051610948816145a4565b60008083601f84011261354a57600080fd5b50813567ffffffffffffffff81111561356257600080fd5b60208301915083602082028301111561357a57600080fd5b9250929050565b8035610948816145b8565b8051610948816145b8565b8051610948816145c1565b8035610948816145ca565b600082601f8301126135be57600080fd5b81356135d16135cc826144ec565b6144c5565b915080825260208301602083018583830111156135ed57600080fd5b6135f8838284614562565b50505092915050565b8035610948816145c1565b60006020828403121561361e57600080fd5b60006118388484613522565b60006020828403121561363c57600080fd5b6000611838848461352d565b6000806040838503121561365b57600080fd5b60006136678585613522565b925050602061367885828601613522565b9150509250929050565b60008060006060848603121561369757600080fd5b60006136a38686613522565b93505060206136b486828701613522565b92505060406136c586828701613601565b9150509250925092565b600080604083850312156136e257600080fd5b60006136ee8585613522565b925050602061367885828601613601565b60008060008060006060868803121561371757600080fd5b853567ffffffffffffffff81111561372e57600080fd5b61373a88828901613538565b9550955050602086013567ffffffffffffffff81111561375957600080fd5b61376588828901613538565b9350935050604061377888828901613581565b9150509295509295909350565b60006020828403121561379757600080fd5b6000611838848461358c565b6000602082840312156137b557600080fd5b60006118388484613597565b6000602082840312156137d357600080fd5b600061183884846135a2565b600080600080608085870312156137f557600080fd5b600061380187876135a2565b945050602085013567ffffffffffffffff81111561381e57600080fd5b61382a878288016135ad565b935050604085013567ffffffffffffffff81111561384757600080fd5b613853878288016135ad565b925050606061386487828801613601565b91505092959194509250565b60006020828403121561388257600080fd5b60006118388484613601565b6000806000806000606086880312156138a657600080fd5b60006138b28888613601565b955050602086013567ffffffffffffffff8111156138cf57600080fd5b6138db88828901613538565b9450945050604086013567ffffffffffffffff8111156138fa57600080fd5b61390688828901613538565b92509250509295509295909350565b6000806040838503121561392857600080fd5b60006136ee8585613601565b60006139408383613963565b505060200190565b60006139408383614168565b61395d81614557565b82525050565b61395d81614527565b60006139778261451a565b613981818561451e565b935061398c83614514565b8060005b838110156139ba5781516139a48882613934565b97506139af83614514565b925050600101613990565b509495945050505050565b60006139d08261451a565b6139da818561451e565b93506139e583614514565b8060005b838110156139ba5781516139fd8882613948565b9750613a0883614514565b9250506001016139e9565b61395d81614532565b61395d8161095b565b61395d81614537565b6000613a398261451a565b613a43818561451e565b9350613a5381856020860161456e565b613a5c8161459a565b9093019392505050565b6000613a7360158361451e565b741858d8dc9d59525b9d195c995cdd0819985a5b1959605a1b815260200192915050565b6000613aa460218361451e565b7f4e6f7420656e6f75676820616c6c6f77616e636520666f72207472616e7366658152603960f91b602082015260400192915050565b6000613ae7600e8361451e565b6d4e6f7420636f6d70617469626c6560901b815260200192915050565b6000613b1160268361451e565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b602082015260400192915050565b6000613b5960208361451e565b7f496e76616c6964206861743a206c656e677468206e6f74206d61746368696e67815260200192915050565b6000613b92600e8361451e565b6d125b9d985b1a59081a185d08125160921b815260200192915050565b6000613bbc601b8361451e565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b6000613bf560288361451e565b7f496e76616c6964206861743a20726563697069656e742073686f756c64206e6f815267074206265203078360c41b602082015260400192915050565b6000613c3f60148361451e565b731d1bdad95b88185c1c1c9bdd994819985a5b195960621b815260200192915050565b6000613c6f60298361451e565b7f546865206c6962726172792068617320616c7265616479206265656e20696e698152683a34b0b634bd32b21760b91b602082015260400192915050565b6000613cba602e8361451e565b7f41646d696e2063616e206f6e6c79206368616e67652068617420666f7220636f81526d6e7472616374206164647265737360901b602082015260400192915050565b6000613d0a60188361451e565b7f7372632073686f756c64206e6f7420657175616c206473740000000000000000815260200192915050565b6000613d43601c8361451e565b7f4e6f7420656e6f7567682062616c616e636520746f2072656465656d00000000815260200192915050565b6000613d7c60328361451e565b7f4e65772073747261746567792073686f756c642068617665207468652073616d81527119481d5b99195c9b1e5a5b99c8185cdcd95d60721b602082015260400192915050565b6000613dd060158361451e565b741d1bdad95b881d1c985b9cd9995c8819985a5b1959605a1b815260200192915050565b6000613e0160218361451e565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b6000613e4460208361451e565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572815260200192915050565b6000613e7d601e8361451e565b7f4e6f7420656e6f7567682062616c616e636520746f207472616e736665720000815260200192915050565b6000613eb6601c8361451e565b7f52656465656d20616d6f756e742063616e6e6f74206265207a65726f00000000815260200192915050565b6000613eef60148361451e565b734e6f7420656e6f75676820616c6c6f77616e636560601b815260200192915050565b6000613f1f60328361451e565b7f496e76616c696c64206861743a206d6178696d756d206e756d626572206f66208152711c9958da5c1a595b9d1cc81c995858da195960721b602082015260400192915050565b6000613f7360338361451e565b7f546865206c696272617279206973206c6f636b65642e204e6f206469726563748152721013b1b0b636139034b99030b63637bbb2b21760691b602082015260400192915050565b6000613fc8602f8361451e565b7f496e76616c6964206861743a2070726f706f7274696f6e2073686f756c64206281526e065206c6172676572207468616e203608c1b602082015260400192915050565b6000614019601f8361451e565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00815260200192915050565b600061405260238361451e565b7f496e76616c6964206861743a206174206c65617374206f6e6520726563697069815262195b9d60ea1b602082015260400192915050565b805160e083019061409b8482613a1c565b5060208201516140ae6020850182613a1c565b5060408201516140c16040850182613a1c565b5060608201516140d46060850182613a1c565b5060808201516140e76080850182613a1c565b5060a08201516140fa60a0850182613a1c565b5060c08201516119e360c0850182613a1c565b8051604083019061411e8482613a1c565b5060208201516119e36020850182613a1c565b805160608301906141428482613a1c565b5060208201516141556020850182613a1c565b5060408201516119e36040850182613a1c565b61395d8161454e565b602081016109488284613963565b6040810161418d8285613954565b6111406020830184613963565b606081016141a88286613954565b6141b56020830185613963565b6118386040830184613a1c565b604081016141d08285613963565b6111406020830184613a1c565b604080825281016141ee818561396c565b9050818103602083015261183881846139c5565b602081016109488284613a13565b6060810161421e8286613a13565b6141b56020830185613a1c565b602081016109488284613a1c565b602081016109488284613a25565b602080825281016111408184613a2e565b6020808252810161094881613a66565b6020808252810161094881613a97565b6020808252810161094881613ada565b6020808252810161094881613b04565b6020808252810161094881613b4c565b6020808252810161094881613b85565b6020808252810161094881613baf565b6020808252810161094881613be8565b6020808252810161094881613c32565b6020808252810161094881613c62565b6020808252810161094881613cad565b6020808252810161094881613cfd565b6020808252810161094881613d36565b6020808252810161094881613d6f565b6020808252810161094881613dc3565b6020808252810161094881613df4565b6020808252810161094881613e37565b6020808252810161094881613e70565b6020808252810161094881613ea9565b6020808252810161094881613ee2565b6020808252810161094881613f12565b6020808252810161094881613f66565b6020808252810161094881613fbb565b602080825281016109488161400c565b6020808252810161094881614045565b60e08101610948828461408a565b60408101610948828461410d565b606081016109488284614131565b606081016144208286613a1c565b8181036020830152614432818561396c565b9050818103604083015261444681846139c5565b95945050505050565b604081016141d08285613a1c565b6060810161421e8286613a1c565b60a081016144798288613a1c565b6144866020830187613a1c565b6144936040830186613a1c565b6144a06060830185613a1c565b6144ad6080830184613a1c565b9695505050505050565b602081016109488284614168565b60405181810167ffffffffffffffff811182821017156144e457600080fd5b604052919050565b600067ffffffffffffffff82111561450357600080fd5b506020601f91909101601f19160190565b60200190565b5190565b90815260200190565b600061094882614542565b151590565b600061094882614527565b6001600160a01b031690565b63ffffffff1690565b600061094882614537565b82818337506000910152565b60005b83811015614589578181015183820152602001614571565b838111156119e35750506000910152565b601f01601f191690565b6145ad81614527565b81146113e957600080fd5b6145ad81614532565b6145ad8161095b565b6145ad8161453756feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa365627a7a72315820966b6f4dc2e27d4ba6b4de3a87038d644cddfec7d29f0dbf0e9342dd9cf74d9b6c6578706572696d656e74616cf564736f6c634300050c0040

Swarm Source

bzzr://966b6f4dc2e27d4ba6b4de3a87038d644cddfec7d29f0dbf0e9342dd9cf74d9b

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.