Contract Address Details

0xB18713Ac02Fc2090c0447e539524a5c76f327a3b

Contract Name
SWAPCAT
Creator
0xc965e0–c5cc12 at 0x6beac4–31be08
Balance
0 EWT ( )
Tokens
Fetching tokens...
Transactions
1 Transactions
Transfers
0 Transfers
Gas Used
116,976
Last Balance Update
29164647
Contract name:
SWAPCAT




Optimization enabled
false
Compiler version
v0.4.26+commit.4563c3fc




EVM Version
default




Verified at
2021-10-13T11:35:56.094046Z

Contract source code

pragma solidity ^0.4.20;

// 😸 WWW.SWAP.CAT 😸
//
// a simple DEX for fixed price token offers directly from wallet to wallet
//
// users can set up erc20 tokens for sale for any other erc20
//
// funds stay in users wallets, dex contract gets a spending allowance
//
// payments go directly into the sellers wallet
//
// this DEX takes no fees
//
// mostly useful to provide stablecoin liquidity or sell tokens for a premium
//
// offers have to be adjusted by the user if prices change
//




// we need the erc20 interface to access the tokens details

interface IERC20 {
    function balanceOf(address account) external view returns (uint256);
    function allowance(address owner, address spender) external view returns (uint256);
    // no return value on transfer and transferFrom to tolerate old erc20 tokens
    // we work around that in the buy function by checking balance twice
    function transferFrom(address sender, address recipient, uint256 amount) external;
    function transfer(address to, uint256 amount) external;
    function decimals() external view returns (uint256);
    function symbol() external view returns (string);
    function name() external view returns (string);

}





contract SWAPCAT {

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// lets make mappings to store offer data

    mapping (uint24 => uint256) internal price;
    mapping (uint24 => address) internal offertoken;
    mapping (uint24 => address) internal buyertoken;
    mapping (uint24 => address) internal seller;
    uint24 internal offercount;


// admin address, receives donations and can move stuck funds, nothing else    
    address internal admin = 0xc965E082B0082449047501032F0E9e7F3DC5Cc12;






////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// set up your erc20 offer. give token addresses and the price in baseunits
// to change a price simply call this again with the changed price + offerid

function makeoffer(address _offertoken, address _buyertoken, uint256 _price, uint24 _offerid) public returns (uint24) {

// if no offerid is given a new offer is made, if offerid is given only the offers price is changed if owner matches
        if(_offerid==0)
                    {
                    _offerid=offercount;
                    offercount++;seller[_offerid]=msg.sender;
                    offertoken[_offerid]=_offertoken;
                    buyertoken[_offerid]=_buyertoken;
                    }
                    else
                    {
                    require(seller[_offerid]==msg.sender,"only original seller can change offer!");
                    }
        price[_offerid]=_price;

// returns the offerid
        return _offerid;
    }
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////









////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// delete an offer

function deleteoffer(uint24 _offerid) public returns (string) {
        require(seller[_offerid]==msg.sender,"only original seller can change offer!");
        delete seller[_offerid];
        delete offertoken[_offerid];
        delete buyertoken[_offerid];
        delete price[_offerid];
        return "offer deleted";
    }
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// return the total number of offers to loop through all offers
// its the web frontends job to keep track of offers

function getoffercount() public view returns (uint24){ return offercount-1;}

//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////






////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// get a tokens name, symbol and decimals 

    function tokeninfo(address _tokenaddr) public view returns (uint256, string, string) {
        IERC20 tokeni = IERC20(_tokenaddr);
        return (tokeni.decimals(),tokeni.symbol(),tokeni.name());
        }   
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////











////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// get a single offers details

    function showoffer(uint24 _offerid) public view returns (address, address, address, uint256, uint256) {
        

        IERC20 offertokeni = IERC20(offertoken[_offerid]);


// get offertokens balance and allowance, whichever is lower is the available amount        
        uint256 availablebalance = offertokeni.balanceOf(seller[_offerid]);
        uint256 availableallow = offertokeni.allowance(seller[_offerid],address(this));

        if(availableallow<availablebalance){availablebalance = availableallow;}

        return (offertoken[_offerid],buyertoken[_offerid],seller[_offerid],price[_offerid],availablebalance);
        
    }   
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////




////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// return the price in buyertokens for the specified amount of offertokens

function pricepreview(uint24 _offerid, uint256 _amount) public view returns (uint256) {
        IERC20 offertokeni = IERC20(offertoken[_offerid]);
        return  _amount * price[_offerid] / (uint256(10) ** offertokeni.decimals())+1;
    }
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////






////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// return the amount in offertokens for the specified amount of buyertokens, for debugging

//function pricepreviewreverse(uint24 _offerid, uint256 _amount) public view returns (uint256) {
//        IERC20 offertokeni = IERC20(offertoken[_offerid]);
//        return  _amount * (uint256(10) ** offertokeni.decimals()) / price[_offerid];
//    }
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////






////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// the actual exchange function
// the buyer must bring the price correctly to ensure no frontrunning / changed offer
// if the offer is changed in meantime, it will not execute

function buy(uint24 _offerid, uint256 _offertokenamount, uint256 _price) public returns (string) {

        IERC20 offertokeninterface = IERC20(offertoken[_offerid]);
        IERC20 buyertokeninterface = IERC20(buyertoken[_offerid]);


// given price is being checked with recorded data from mappings
       require(price[_offerid] == _price,"offer price wrong");


// calculate the price of the order
        uint256 buyertokenAmount =  _offertokenamount * _price / (uint256(10) ** offertokeninterface.decimals())+1;


////// these 4 checks have been spared out since the final check suffices, this save ~50000 gas
////        // check if the buyers allowance and balance are right
////                require(buyertokeninterface.allowance(msg.sender, address(this)) >= buyertokenAmount, "Check the buyers token allowance");
////                require(buyertokeninterface.balanceOf(msg.sender) >= buyertokenAmount,"buyer not enough to pay");
////        // check if the sellers allowance and balance are right        
////                require(offertokeninterface.allowance(seller[_offerid], address(this)) >= _offertokenamount, "Check the sellers token allowance");
////                require(offertokeninterface.balanceOf(seller[_offerid]) >= _offertokenamount,"seller not enough on stock");
  
        
// some old erc20 tokens give no return value so we must work around by getting their balance before and after the exchange        
        uint256 oldbuyerbalance = buyertokeninterface.balanceOf(msg.sender);
        uint256 oldsellerbalance = offertokeninterface.balanceOf(seller[_offerid]);


// finally do the exchange        
        buyertokeninterface.transferFrom(msg.sender,seller[_offerid], buyertokenAmount);
        offertokeninterface.transferFrom(seller[_offerid],msg.sender,_offertokenamount);


// now check if the balances changed on both accounts.
// we do not check for exact amounts since some tokens behave differently with fees, burnings, etc
// we assume if both balances are higher than before all is good
        require(oldbuyerbalance > buyertokeninterface.balanceOf(msg.sender),"buyer error");
        require(oldsellerbalance > offertokeninterface.balanceOf(seller[_offerid]),"seller error");
        return "tokens exchanged. ENJOY!";
    }
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////












////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// in case someone wrongfully directly sends erc20 to this contract address, the admin can move them out
function losttokens(address token) public {
        IERC20 tokeninterface = IERC20(token);
        tokeninterface.transfer(admin,tokeninterface.balanceOf(address(this)));
}
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// straight ether payments to this contract are considered donations. thank you!
function () public payable {admin.transfer(address(this).balance);        }
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////






}
        

Contract ABI

[{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""},{"type":"string","name":""},{"type":"string","name":""}],"name":"tokeninfo","inputs":[{"type":"address","name":"_tokenaddr"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"losttokens","inputs":[{"type":"address","name":"token"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"string","name":""}],"name":"deleteoffer","inputs":[{"type":"uint24","name":"_offerid"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"uint24","name":""}],"name":"makeoffer","inputs":[{"type":"address","name":"_offertoken"},{"type":"address","name":"_buyertoken"},{"type":"uint256","name":"_price"},{"type":"uint24","name":"_offerid"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""},{"type":"address","name":""},{"type":"address","name":""},{"type":"uint256","name":""},{"type":"uint256","name":""}],"name":"showoffer","inputs":[{"type":"uint24","name":"_offerid"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"pricepreview","inputs":[{"type":"uint24","name":"_offerid"},{"type":"uint256","name":"_amount"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"string","name":""}],"name":"buy","inputs":[{"type":"uint24","name":"_offerid"},{"type":"uint256","name":"_offertokenamount"},{"type":"uint256","name":"_price"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint24","name":""}],"name":"getoffercount","inputs":[],"constant":true},{"type":"fallback","stateMutability":"payable","payable":true}]
            

Deployed ByteCode

0x60806040526004361061008e576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806364473a1214610110578063657ce0ef1461023f5780636a540b741461028257806374759ae41461032d57806394b1a131146103c7578063c2250f8b146104ad578063e3ca70b0146104fd578063e3fb4aea146105bc575b600460039054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f1935050505015801561010d573d6000803e3d6000fd5b50005b34801561011c57600080fd5b50610151600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506105f1565b604051808481526020018060200180602001838103835285818151815260200191508051906020019080838360005b8381101561019b578082015181840152602081019050610180565b50505050905090810190601f1680156101c85780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b838110156102015780820151818401526020810190506101e6565b50505050905090810190601f16801561022e5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b34801561024b57600080fd5b50610280600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610892565b005b34801561028e57600080fd5b506102b2600480360381019080803562ffffff169060200190929190505050610a4d565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156102f25780820151818401526020810190506102d7565b50505050905090810190601f16801561031f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561033957600080fd5b506103a7600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803562ffffff169060200190929190505050610c72565b604051808262ffffff1662ffffff16815260200191505060405180910390f35b3480156103d357600080fd5b506103f7600480360381019080803562ffffff169060200190929190505050610f19565b604051808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018281526020019550505050505060405180910390f35b3480156104b957600080fd5b506104e7600480360381019080803562ffffff169060200190929190803590602001909291905050506112bd565b6040518082815260200191505060405180910390f35b34801561050957600080fd5b50610541600480360381019080803562ffffff16906020019092919080359060200190929190803590602001909291905050506113d7565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610581578082015181840152602081019050610566565b50505050905090810190601f1680156105ae5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156105c857600080fd5b506105d1611d06565b604051808262ffffff1662ffffff16815260200191505060405180910390f35b600060608060008490508073ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561065f57600080fd5b505af1158015610673573d6000803e3d6000fd5b505050506040513d602081101561068957600080fd5b81019080805190602001909291905050508173ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401600060405180830381600087803b1580156106fe57600080fd5b505af1158015610712573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250602081101561073c57600080fd5b81019080805164010000000081111561075457600080fd5b8281019050602081018481111561076a57600080fd5b815185600182028301116401000000008211171561078757600080fd5b50509291905050508273ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401600060405180830381600087803b1580156107f357600080fd5b505af1158015610807573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250602081101561083157600080fd5b81019080805164010000000081111561084957600080fd5b8281019050602081018481111561085f57600080fd5b815185600182028301116401000000008211171561087c57600080fd5b5050929190505050935093509350509193909250565b60008190508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb600460039054906101000a900473ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b15801561097157600080fd5b505af1158015610985573d6000803e3d6000fd5b505050506040513d602081101561099b57600080fd5b81019080805190602001909291905050506040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b158015610a3157600080fd5b505af1158015610a45573d6000803e3d6000fd5b505050505050565b60603373ffffffffffffffffffffffffffffffffffffffff16600360008462ffffff1662ffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515610b55576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f6f6e6c79206f726967696e616c2073656c6c65722063616e206368616e67652081526020017f6f6666657221000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b600360008362ffffff1662ffffff16815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600160008362ffffff1662ffffff16815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600260008362ffffff1662ffffff16815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000808362ffffff1662ffffff168152602001908152602001600020600090556040805190810160405280600d81526020017f6f666665722064656c65746564000000000000000000000000000000000000008152509050919050565b6000808262ffffff161415610de657600460009054906101000a900462ffffff1691506004600081819054906101000a900462ffffff168092919060010191906101000a81548162ffffff021916908362ffffff1602179055505033600360008462ffffff1662ffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084600160008462ffffff1662ffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600260008462ffffff1662ffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610eed565b3373ffffffffffffffffffffffffffffffffffffffff16600360008462ffffff1662ffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515610eec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f6f6e6c79206f726967696e616c2073656c6c65722063616e206368616e67652081526020017f6f6666657221000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b5b826000808462ffffff1662ffffff16815260200190815260200160002081905550819050949350505050565b600080600080600080600080600160008a62ffffff1662ffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1692508273ffffffffffffffffffffffffffffffffffffffff166370a08231600360008c62ffffff1662ffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b15801561103d57600080fd5b505af1158015611051573d6000803e3d6000fd5b505050506040513d602081101561106757600080fd5b810190808051906020019092919050505091508273ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e600360008c62ffffff1662ffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16306040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b15801561118657600080fd5b505af115801561119a573d6000803e3d6000fd5b505050506040513d60208110156111b057600080fd5b81019080805190602001909291905050509050818110156111cf578091505b600160008a62ffffff1662ffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008b62ffffff1662ffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600360008c62ffffff1662ffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000808d62ffffff1662ffffff16815260200190815260200160002054859750975097509750975050505091939590929450565b600080600160008562ffffff1662ffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060018173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561136657600080fd5b505af115801561137a573d6000803e3d6000fd5b505050506040513d602081101561139057600080fd5b8101908080519060200190929190505050600a0a6000808762ffffff1662ffffff1681526020019081526020016000205485028115156113cc57fe5b040191505092915050565b60606000806000806000600160008a62ffffff1662ffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169450600260008a62ffffff1662ffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169350866000808b62ffffff1662ffffff168152602001908152602001600020541415156114f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f6f666665722070726963652077726f6e6700000000000000000000000000000081525060200191505060405180910390fd5b60018573ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561155a57600080fd5b505af115801561156e573d6000803e3d6000fd5b505050506040513d602081101561158457600080fd5b8101908080519060200190929190505050600a0a888a028115156115a457fe5b040192508373ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b15801561164357600080fd5b505af1158015611657573d6000803e3d6000fd5b505050506040513d602081101561166d57600080fd5b810190808051906020019092919050505091508473ffffffffffffffffffffffffffffffffffffffff166370a08231600360008c62ffffff1662ffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b15801561175857600080fd5b505af115801561176c573d6000803e3d6000fd5b505050506040513d602081101561178257600080fd5b810190808051906020019092919050505090508373ffffffffffffffffffffffffffffffffffffffff166323b872dd33600360008d62ffffff1662ffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16866040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b1580156118a957600080fd5b505af11580156118bd573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff166323b872dd600360008c62ffffff1662ffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16338b6040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b1580156119d557600080fd5b505af11580156119e9573d6000803e3d6000fd5b505050508373ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b158015611a8857600080fd5b505af1158015611a9c573d6000803e3d6000fd5b505050506040513d6020811015611ab257600080fd5b810190808051906020019092919050505082111515611b39576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600b8152602001807f6275796572206572726f7200000000000000000000000000000000000000000081525060200191505060405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff166370a08231600360008c62ffffff1662ffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b158015611c1157600080fd5b505af1158015611c25573d6000803e3d6000fd5b505050506040513d6020811015611c3b57600080fd5b810190808051906020019092919050505081111515611cc2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f73656c6c6572206572726f72000000000000000000000000000000000000000081525060200191505060405180910390fd5b6040805190810160405280601881526020017f746f6b656e732065786368616e6765642e20454e4a4f59210000000000000000815250955050505050509392505050565b60006001600460009054906101000a900462ffffff16039050905600a165627a7a7230582029d4b40c2a0a7dddc459944b3d46564299fa06f797350a045061c7471dc0d43e0029