Transactions
Token Transfers
Tokens
Internal Transactions
Coin Balance History
Logs
Code
Read Contract
Write Contract
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
This contract has been partially verified via Sourcify.
View contract in Sourcify repository
- Contract name:
- DutchAuction
- Optimization enabled
- false
- Compiler version
- v0.4.10+commit.f0d539ae
- Verified at
- 2026-04-13T00:54:40.305603Z
Constructor Arguments
000000000000000000000000851b7f3ab81bd8df354f0d7640efcd72885534190000000000000000000000000000000000000000000034f086f3b33b684000000000000000000000000000000000000000000000000000000000000000001194
Arg [0] (address) : 0x851b7f3ab81bd8df354f0d7640efcd7288553419
Arg [1] (uint256) : 250000000000000000000000
Arg [2] (uint256) : 4500
DutchAuction.sol
pragma solidity 0.4.10;
/// @title Abstract token contract - Functions to be implemented by token contracts.
contract Token {
function transfer(address to, uint256 value) returns (bool success);
function transferFrom(address from, address to, uint256 value) returns (bool success);
function approve(address spender, uint256 value) returns (bool success);
// This is not an abstract function, because solc won't recognize generated getter functions for public variables as functions.
function totalSupply() constant returns (uint256 supply) {}
function balanceOf(address owner) constant returns (uint256 balance);
function allowance(address owner, address spender) constant returns (uint256 remaining);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
/// @title Dutch auction contract - distribution of Gnosis tokens using an auction.
/// @author Stefan George - <stefan.george@consensys.net>
contract DutchAuction {
/*
* Events
*/
event BidSubmission(address indexed sender, uint256 amount);
/*
* Constants
*/
uint constant public MAX_TOKENS_SOLD = 9000000 * 10**18; // 9M
uint constant public WAITING_PERIOD = 7 days;
/*
* Storage
*/
Token public gnosisToken;
address public wallet;
address public owner;
uint public ceiling;
uint public priceFactor;
uint public startBlock;
uint public endTime;
uint public totalReceived;
uint public finalPrice;
mapping (address => uint) public bids;
Stages public stage;
/*
* Enums
*/
enum Stages {
AuctionDeployed,
AuctionSetUp,
AuctionStarted,
AuctionEnded,
TradingStarted
}
/*
* Modifiers
*/
modifier atStage(Stages _stage) {
if (stage != _stage)
// Contract not in expected state
throw;
_;
}
modifier isOwner() {
if (msg.sender != owner)
// Only owner is allowed to proceed
throw;
_;
}
modifier isWallet() {
if (msg.sender != wallet)
// Only wallet is allowed to proceed
throw;
_;
}
modifier isValidPayload() {
if (msg.data.length != 4 && msg.data.length != 36)
throw;
_;
}
modifier timedTransitions() {
if (stage == Stages.AuctionStarted && calcTokenPrice() <= calcStopPrice())
finalizeAuction();
if (stage == Stages.AuctionEnded && now > endTime + WAITING_PERIOD)
stage = Stages.TradingStarted;
_;
}
/*
* Public functions
*/
/// @dev Contract constructor function sets owner.
/// @param _wallet Gnosis wallet.
/// @param _ceiling Auction ceiling.
/// @param _priceFactor Auction price factor.
function DutchAuction(address _wallet, uint _ceiling, uint _priceFactor)
public
{
if (_wallet == 0 || _ceiling == 0 || _priceFactor == 0)
// Arguments are null.
throw;
owner = msg.sender;
wallet = _wallet;
ceiling = _ceiling;
priceFactor = _priceFactor;
stage = Stages.AuctionDeployed;
}
/// @dev Setup function sets external contracts' addresses.
/// @param _gnosisToken Gnosis token address.
function setup(address _gnosisToken)
public
isOwner
atStage(Stages.AuctionDeployed)
{
if (_gnosisToken == 0)
// Argument is null.
throw;
gnosisToken = Token(_gnosisToken);
// Validate token balance
if (gnosisToken.balanceOf(this) != MAX_TOKENS_SOLD)
throw;
stage = Stages.AuctionSetUp;
}
/// @dev Starts auction and sets startBlock.
function startAuction()
public
isWallet
atStage(Stages.AuctionSetUp)
{
stage = Stages.AuctionStarted;
startBlock = block.number;
}
/// @dev Changes auction ceiling and start price factor before auction is started.
/// @param _ceiling Updated auction ceiling.
/// @param _priceFactor Updated start price factor.
function changeSettings(uint _ceiling, uint _priceFactor)
public
isWallet
atStage(Stages.AuctionSetUp)
{
ceiling = _ceiling;
priceFactor = _priceFactor;
}
/// @dev Calculates current token price.
/// @return Returns token price.
function calcCurrentTokenPrice()
public
timedTransitions
returns (uint)
{
if (stage == Stages.AuctionEnded || stage == Stages.TradingStarted)
return finalPrice;
return calcTokenPrice();
}
/// @dev Returns correct stage, even if a function with timedTransitions modifier has not yet been called yet.
/// @return Returns current auction stage.
function updateStage()
public
timedTransitions
returns (Stages)
{
return stage;
}
/// @dev Allows to send a bid to the auction.
/// @param receiver Bid will be assigned to this address if set.
function bid(address receiver)
public
payable
isValidPayload
timedTransitions
atStage(Stages.AuctionStarted)
returns (uint amount)
{
// If a bid is done on behalf of a user via ShapeShift, the receiver address is set.
if (receiver == 0)
receiver = msg.sender;
amount = msg.value;
// Prevent that more than 90% of tokens are sold. Only relevant if cap not reached.
uint maxWei = (MAX_TOKENS_SOLD / 10**18) * calcTokenPrice() - totalReceived;
uint maxWeiBasedOnTotalReceived = ceiling - totalReceived;
if (maxWeiBasedOnTotalReceived < maxWei)
maxWei = maxWeiBasedOnTotalReceived;
// Only invest maximum possible amount.
if (amount > maxWei) {
amount = maxWei;
// Send change back to receiver address. In case of a ShapeShift bid the user receives the change back directly.
if (!receiver.send(msg.value - amount))
// Sending failed
throw;
}
// Forward funding to ether wallet
if (amount == 0 || !wallet.send(amount))
// No amount sent or sending failed
throw;
bids[receiver] += amount;
totalReceived += amount;
if (maxWei == amount)
// When maxWei is equal to the big amount the auction is ended and finalizeAuction is triggered.
finalizeAuction();
BidSubmission(receiver, amount);
}
/// @dev Claims tokens for bidder after auction.
/// @param receiver Tokens will be assigned to this address if set.
function claimTokens(address receiver)
public
isValidPayload
timedTransitions
atStage(Stages.TradingStarted)
{
if (receiver == 0)
receiver = msg.sender;
uint tokenCount = bids[receiver] * 10**18 / finalPrice;
bids[receiver] = 0;
gnosisToken.transfer(receiver, tokenCount);
}
/// @dev Calculates stop price.
/// @return Returns stop price.
function calcStopPrice()
constant
public
returns (uint)
{
return totalReceived * 10**18 / MAX_TOKENS_SOLD + 1;
}
/// @dev Calculates token price.
/// @return Returns token price.
function calcTokenPrice()
constant
public
returns (uint)
{
return priceFactor * 10**18 / (block.number - startBlock + 7500) + 1;
}
/*
* Private functions
*/
function finalizeAuction()
private
{
stage = Stages.AuctionEnded;
if (totalReceived == ceiling)
finalPrice = calcTokenPrice();
else
finalPrice = calcStopPrice();
uint soldTokens = totalReceived * 10**18 / finalPrice;
// Auction contract transfers all unsold tokens to Gnosis inventory multisig
gnosisToken.transfer(wallet, MAX_TOKENS_SOLD - soldTokens);
endTime = now;
}
}
Compiler Settings
{"remappings":[],"optimizer":{"runs":200,"enabled":false},"libraries":{},"compilationTarget":{"DutchAuction.sol":"DutchAuction"}}
Contract ABI
[{"type":"function","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"MAX_TOKENS_SOLD","inputs":[],"constant":true},{"type":"function","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"endTime","inputs":[],"constant":true},{"type":"function","payable":false,"outputs":[],"name":"changeSettings","inputs":[{"type":"uint256","name":"_ceiling"},{"type":"uint256","name":"_priceFactor"}],"constant":false},{"type":"function","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"calcTokenPrice","inputs":[],"constant":true},{"type":"function","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"startBlock","inputs":[],"constant":true},{"type":"function","payable":false,"outputs":[{"type":"address","name":""}],"name":"wallet","inputs":[],"constant":true},{"type":"function","payable":false,"outputs":[{"type":"address","name":""}],"name":"gnosisToken","inputs":[],"constant":true},{"type":"function","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"bids","inputs":[{"type":"address","name":""}],"constant":true},{"type":"function","payable":false,"outputs":[],"name":"setup","inputs":[{"type":"address","name":"_gnosisToken"}],"constant":false},{"type":"function","payable":false,"outputs":[],"name":"startAuction","inputs":[],"constant":false},{"type":"function","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"WAITING_PERIOD","inputs":[],"constant":true},{"type":"function","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"ceiling","inputs":[],"constant":true},{"type":"function","payable":false,"outputs":[{"type":"address","name":""}],"name":"owner","inputs":[],"constant":true},{"type":"function","payable":true,"outputs":[{"type":"uint256","name":"amount"}],"name":"bid","inputs":[{"type":"address","name":"receiver"}],"constant":false},{"type":"function","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"totalReceived","inputs":[],"constant":true},{"type":"function","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"finalPrice","inputs":[],"constant":true},{"type":"function","payable":false,"outputs":[{"type":"uint8","name":""}],"name":"stage","inputs":[],"constant":true},{"type":"function","payable":false,"outputs":[{"type":"uint8","name":""}],"name":"updateStage","inputs":[],"constant":false},{"type":"function","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"calcCurrentTokenPrice","inputs":[],"constant":false},{"type":"function","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"calcStopPrice","inputs":[],"constant":true},{"type":"function","payable":false,"outputs":[],"name":"claimTokens","inputs":[{"type":"address","name":"receiver"}],"constant":false},{"type":"function","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"priceFactor","inputs":[],"constant":true},{"type":"constructor","payable":false,"inputs":[{"type":"address","name":"_wallet"},{"type":"uint256","name":"_ceiling"},{"type":"uint256","name":"_priceFactor"}]},{"type":"event","name":"BidSubmission","inputs":[{"type":"address","name":"sender","indexed":true},{"type":"uint256","name":"amount","indexed":false}],"anonymous":false}]
Contract Creation Code
0x6060604052341561000c57fe5b6040516060806114cc833981016040528080519060200190919080519060200190919080519060200190919050505b60008373ffffffffffffffffffffffffffffffffffffffff1614806100605750600082145b8061006b5750600081145b156100765760006000fd5b33600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600381905550806004819055506000600a60006101000a81548160ff0219169083600481111561012557fe5b02179055505b5050505b61138e8061013e6000396000f30060606040523615610126576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806317f5de95146101285780633197cbb61461014e57806336d02c941461017457806339f64b521461019d57806348cd4cb1146101c3578063521eb273146101e957806360fd902c1461023b57806362ea82db1461028d57806366d38203146102d75780636b64c7691461030d5780636f85c7e41461031f578063753ed1bd146103455780638da5cb5b1461036b5780639cf5453d146103bd578063a3c2c462146103ff578063a6b513ee14610425578063c040e6b81461044b578063c062f5781461047f578063d9f8a4e2146104b3578063dd9dd688146104d9578063df8de3e7146104ff578063dfb2866d14610535575bfe5b341561013057fe5b61013861055b565b6040518082815260200191505060405180910390f35b341561015657fe5b61015e61056a565b6040518082815260200191505060405180910390f35b341561017c57fe5b61019b6004808035906020019091908035906020019091905050610570565b005b34156101a557fe5b6101ad610619565b6040518082815260200191505060405180910390f35b34156101cb57fe5b6101d3610644565b6040518082815260200191505060405180910390f35b34156101f157fe5b6101f961064a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561024357fe5b61024b610670565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561029557fe5b6102c1600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610696565b6040518082815260200191505060405180910390f35b34156102df57fe5b61030b600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506106ae565b005b341561031557fe5b61031d6108c4565b005b341561032757fe5b61032f610988565b6040518082815260200191505060405180910390f35b341561034d57fe5b61035561098f565b6040518082815260200191505060405180910390f35b341561037357fe5b61037b610995565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103e9600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506109bb565b6040518082815260200191505060405180910390f35b341561040757fe5b61040f610cc6565b6040518082815260200191505060405180910390f35b341561042d57fe5b610435610ccc565b6040518082815260200191505060405180910390f35b341561045357fe5b61045b610cd2565b6040518082600481111561046b57fe5b60ff16815260200191505060405180910390f35b341561048757fe5b61048f610ce5565b6040518082600481111561049f57fe5b60ff16815260200191505060405180910390f35b34156104bb57fe5b6104c3610db4565b6040518082815260200191505060405180910390f35b34156104e157fe5b6104e9610ee3565b6040518082815260200191505060405180910390f35b341561050757fe5b610533600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610f11565b005b341561053d57fe5b6105456111d0565b6040518082815260200191505060405180910390f35b6a0771d2fa45345aa900000081565b60065481565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156105cd5760006000fd5b60018060048111156105db57fe5b600a60009054906101000a900460ff1660048111156105f657fe5b1415156106035760006000fd5b82600381905550816004819055505b5b505b5050565b60006001611d4c600554430301670de0b6b3a76400006004540281151561063c57fe5b040190505b90565b60055481565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60096020528060005260406000206000915090505481565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561070b5760006000fd5b600080600481111561071957fe5b600a60009054906101000a900460ff16600481111561073457fe5b1415156107415760006000fd5b60008273ffffffffffffffffffffffffffffffffffffffff1614156107665760006000fd5b81600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506a0771d2fa45345aa9000000600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b151561087557fe5b60325a03f1151561088257fe5b505050604051805190501415156108995760006000fd5b6001600a60006101000a81548160ff021916908360048111156108b857fe5b02179055505b5b505b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156109215760006000fd5b600180600481111561092f57fe5b600a60009054906101000a900460ff16600481111561094a57fe5b1415156109575760006000fd5b6002600a60006101000a81548160ff0219169083600481111561097657fe5b0217905550436005819055505b5b505b565b62093a8081565b60035481565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006000600060046000369050141580156109db57506024600036905014155b156109e65760006000fd5b600260048111156109f357fe5b600a60009054906101000a900460ff166004811115610a0e57fe5b148015610a295750610a1e610ee3565b610a26610619565b11155b15610a3757610a366111d6565b5b60036004811115610a4457fe5b600a60009054906101000a900460ff166004811115610a5f57fe5b148015610a72575062093a806006540142115b15610a9c576004600a60006101000a81548160ff02191690836004811115610a9657fe5b02179055505b6002806004811115610aaa57fe5b600a60009054906101000a900460ff166004811115610ac557fe5b141515610ad25760006000fd5b60008573ffffffffffffffffffffffffffffffffffffffff161415610af5573394505b349350600754610b03610619565b670de0b6b3a76400006a0771d2fa45345aa9000000811515610b2157fe5b040203925060075460035403915082821015610b3b578192505b82841115610b8d578293508473ffffffffffffffffffffffffffffffffffffffff166108fc8534039081150290604051809050600060405180830381858888f193505050501515610b8c5760006000fd5b5b6000841480610bf35750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051809050600060405180830381858888f19350505050155b15610bfe5760006000fd5b83600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508360076000828254019250508190555083831415610c6c57610c6b6111d6565b5b8473ffffffffffffffffffffffffffffffffffffffff167f9c89e828e6cee6374b68147c9e753e41746aad98ba255a527a4fc0ac1868bff9856040518082815260200191505060405180910390a25b5b505b5b5050919050565b60075481565b60085481565b600a60009054906101000a900460ff1681565b600060026004811115610cf457fe5b600a60009054906101000a900460ff166004811115610d0f57fe5b148015610d2a5750610d1f610ee3565b610d27610619565b11155b15610d3857610d376111d6565b5b60036004811115610d4557fe5b600a60009054906101000a900460ff166004811115610d6057fe5b148015610d73575062093a806006540142115b15610d9d576004600a60006101000a81548160ff02191690836004811115610d9757fe5b02179055505b600a60009054906101000a900460ff1690505b5b90565b600060026004811115610dc357fe5b600a60009054906101000a900460ff166004811115610dde57fe5b148015610df95750610dee610ee3565b610df6610619565b11155b15610e0757610e066111d6565b5b60036004811115610e1457fe5b600a60009054906101000a900460ff166004811115610e2f57fe5b148015610e42575062093a806006540142115b15610e6c576004600a60006101000a81548160ff02191690836004811115610e6657fe5b02179055505b60036004811115610e7957fe5b600a60009054906101000a900460ff166004811115610e9457fe5b1480610ec5575060046004811115610ea857fe5b600a60009054906101000a900460ff166004811115610ec357fe5b145b15610ed4576008549050610edf565b610edc610619565b90505b5b90565b600060016a0771d2fa45345aa9000000670de0b6b3a764000060075402811515610f0957fe5b040190505b90565b60006004600036905014158015610f2d57506024600036905014155b15610f385760006000fd5b60026004811115610f4557fe5b600a60009054906101000a900460ff166004811115610f6057fe5b148015610f7b5750610f70610ee3565b610f78610619565b11155b15610f8957610f886111d6565b5b60036004811115610f9657fe5b600a60009054906101000a900460ff166004811115610fb157fe5b148015610fc4575062093a806006540142115b15610fee576004600a60006101000a81548160ff02191690836004811115610fe857fe5b02179055505b6004806004811115610ffc57fe5b600a60009054906101000a900460ff16600481111561101757fe5b1415156110245760006000fd5b60008373ffffffffffffffffffffffffffffffffffffffff161415611047573392505b600854670de0b6b3a7640000600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540281151561109d57fe5b0491506000600960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15156111af57fe5b60325a03f115156111bc57fe5b50505060405180519050505b5b505b5b5050565b60045481565b60006003600a60006101000a81548160ff021916908360048111156111f757fe5b0217905550600354600754141561121b57611210610619565b60088190555061122a565b611223610ee3565b6008819055505b600854670de0b6b3a76400006007540281151561124357fe5b049050600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836a0771d2fa45345aa9000000036000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b151561133f57fe5b60325a03f1151561134c57fe5b5050506040518051905050426006819055505b505600a165627a7a7230582019150351acc806d091a9cbd411ffcd0b514c1e1aeff90636bdca53a84875f6950029000000000000000000000000851b7f3ab81bd8df354f0d7640efcd72885534190000000000000000000000000000000000000000000034f086f3b33b684000000000000000000000000000000000000000000000000000000000000000001194
Deployed ByteCode
0x60606040523615610126576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806317f5de95146101285780633197cbb61461014e57806336d02c941461017457806339f64b521461019d57806348cd4cb1146101c3578063521eb273146101e957806360fd902c1461023b57806362ea82db1461028d57806366d38203146102d75780636b64c7691461030d5780636f85c7e41461031f578063753ed1bd146103455780638da5cb5b1461036b5780639cf5453d146103bd578063a3c2c462146103ff578063a6b513ee14610425578063c040e6b81461044b578063c062f5781461047f578063d9f8a4e2146104b3578063dd9dd688146104d9578063df8de3e7146104ff578063dfb2866d14610535575bfe5b341561013057fe5b61013861055b565b6040518082815260200191505060405180910390f35b341561015657fe5b61015e61056a565b6040518082815260200191505060405180910390f35b341561017c57fe5b61019b6004808035906020019091908035906020019091905050610570565b005b34156101a557fe5b6101ad610619565b6040518082815260200191505060405180910390f35b34156101cb57fe5b6101d3610644565b6040518082815260200191505060405180910390f35b34156101f157fe5b6101f961064a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561024357fe5b61024b610670565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561029557fe5b6102c1600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610696565b6040518082815260200191505060405180910390f35b34156102df57fe5b61030b600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506106ae565b005b341561031557fe5b61031d6108c4565b005b341561032757fe5b61032f610988565b6040518082815260200191505060405180910390f35b341561034d57fe5b61035561098f565b6040518082815260200191505060405180910390f35b341561037357fe5b61037b610995565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103e9600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506109bb565b6040518082815260200191505060405180910390f35b341561040757fe5b61040f610cc6565b6040518082815260200191505060405180910390f35b341561042d57fe5b610435610ccc565b6040518082815260200191505060405180910390f35b341561045357fe5b61045b610cd2565b6040518082600481111561046b57fe5b60ff16815260200191505060405180910390f35b341561048757fe5b61048f610ce5565b6040518082600481111561049f57fe5b60ff16815260200191505060405180910390f35b34156104bb57fe5b6104c3610db4565b6040518082815260200191505060405180910390f35b34156104e157fe5b6104e9610ee3565b6040518082815260200191505060405180910390f35b341561050757fe5b610533600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610f11565b005b341561053d57fe5b6105456111d0565b6040518082815260200191505060405180910390f35b6a0771d2fa45345aa900000081565b60065481565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156105cd5760006000fd5b60018060048111156105db57fe5b600a60009054906101000a900460ff1660048111156105f657fe5b1415156106035760006000fd5b82600381905550816004819055505b5b505b5050565b60006001611d4c600554430301670de0b6b3a76400006004540281151561063c57fe5b040190505b90565b60055481565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60096020528060005260406000206000915090505481565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561070b5760006000fd5b600080600481111561071957fe5b600a60009054906101000a900460ff16600481111561073457fe5b1415156107415760006000fd5b60008273ffffffffffffffffffffffffffffffffffffffff1614156107665760006000fd5b81600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506a0771d2fa45345aa9000000600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b151561087557fe5b60325a03f1151561088257fe5b505050604051805190501415156108995760006000fd5b6001600a60006101000a81548160ff021916908360048111156108b857fe5b02179055505b5b505b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156109215760006000fd5b600180600481111561092f57fe5b600a60009054906101000a900460ff16600481111561094a57fe5b1415156109575760006000fd5b6002600a60006101000a81548160ff0219169083600481111561097657fe5b0217905550436005819055505b5b505b565b62093a8081565b60035481565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006000600060046000369050141580156109db57506024600036905014155b156109e65760006000fd5b600260048111156109f357fe5b600a60009054906101000a900460ff166004811115610a0e57fe5b148015610a295750610a1e610ee3565b610a26610619565b11155b15610a3757610a366111d6565b5b60036004811115610a4457fe5b600a60009054906101000a900460ff166004811115610a5f57fe5b148015610a72575062093a806006540142115b15610a9c576004600a60006101000a81548160ff02191690836004811115610a9657fe5b02179055505b6002806004811115610aaa57fe5b600a60009054906101000a900460ff166004811115610ac557fe5b141515610ad25760006000fd5b60008573ffffffffffffffffffffffffffffffffffffffff161415610af5573394505b349350600754610b03610619565b670de0b6b3a76400006a0771d2fa45345aa9000000811515610b2157fe5b040203925060075460035403915082821015610b3b578192505b82841115610b8d578293508473ffffffffffffffffffffffffffffffffffffffff166108fc8534039081150290604051809050600060405180830381858888f193505050501515610b8c5760006000fd5b5b6000841480610bf35750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051809050600060405180830381858888f19350505050155b15610bfe5760006000fd5b83600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508360076000828254019250508190555083831415610c6c57610c6b6111d6565b5b8473ffffffffffffffffffffffffffffffffffffffff167f9c89e828e6cee6374b68147c9e753e41746aad98ba255a527a4fc0ac1868bff9856040518082815260200191505060405180910390a25b5b505b5b5050919050565b60075481565b60085481565b600a60009054906101000a900460ff1681565b600060026004811115610cf457fe5b600a60009054906101000a900460ff166004811115610d0f57fe5b148015610d2a5750610d1f610ee3565b610d27610619565b11155b15610d3857610d376111d6565b5b60036004811115610d4557fe5b600a60009054906101000a900460ff166004811115610d6057fe5b148015610d73575062093a806006540142115b15610d9d576004600a60006101000a81548160ff02191690836004811115610d9757fe5b02179055505b600a60009054906101000a900460ff1690505b5b90565b600060026004811115610dc357fe5b600a60009054906101000a900460ff166004811115610dde57fe5b148015610df95750610dee610ee3565b610df6610619565b11155b15610e0757610e066111d6565b5b60036004811115610e1457fe5b600a60009054906101000a900460ff166004811115610e2f57fe5b148015610e42575062093a806006540142115b15610e6c576004600a60006101000a81548160ff02191690836004811115610e6657fe5b02179055505b60036004811115610e7957fe5b600a60009054906101000a900460ff166004811115610e9457fe5b1480610ec5575060046004811115610ea857fe5b600a60009054906101000a900460ff166004811115610ec357fe5b145b15610ed4576008549050610edf565b610edc610619565b90505b5b90565b600060016a0771d2fa45345aa9000000670de0b6b3a764000060075402811515610f0957fe5b040190505b90565b60006004600036905014158015610f2d57506024600036905014155b15610f385760006000fd5b60026004811115610f4557fe5b600a60009054906101000a900460ff166004811115610f6057fe5b148015610f7b5750610f70610ee3565b610f78610619565b11155b15610f8957610f886111d6565b5b60036004811115610f9657fe5b600a60009054906101000a900460ff166004811115610fb157fe5b148015610fc4575062093a806006540142115b15610fee576004600a60006101000a81548160ff02191690836004811115610fe857fe5b02179055505b6004806004811115610ffc57fe5b600a60009054906101000a900460ff16600481111561101757fe5b1415156110245760006000fd5b60008373ffffffffffffffffffffffffffffffffffffffff161415611047573392505b600854670de0b6b3a7640000600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540281151561109d57fe5b0491506000600960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15156111af57fe5b60325a03f115156111bc57fe5b50505060405180519050505b5b505b5b5050565b60045481565b60006003600a60006101000a81548160ff021916908360048111156111f757fe5b0217905550600354600754141561121b57611210610619565b60088190555061122a565b611223610ee3565b6008819055505b600854670de0b6b3a76400006007540281151561124357fe5b049050600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836a0771d2fa45345aa9000000036000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b151561133f57fe5b60325a03f1151561134c57fe5b5050506040518051905050426006819055505b505600a165627a7a7230582019150351acc806d091a9cbd411ffcd0b514c1e1aeff90636bdca53a84875f6950029