Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- WrappedPinakion
- Optimization enabled
- true
- Compiler version
- v0.4.26+commit.4563c3fc
- Optimization runs
- 1
- EVM Version
- default
- Verified at
- 2021-05-11T14:13:39.261875Z
Contract source code
// File: openzeppelin-eth/contracts/zos-lib/Initializable.sol
pragma solidity ^0.4.24;
/**
* @title Initializable
*
* @dev Helper contract to support initializer functions. To use it, replace
* the constructor with a function that has the `initializer` modifier.
* WARNING: Unlike constructors, initializer functions must be manually
* invoked. This applies both to deploying an Initializable contract, as well
* as extending an Initializable contract via inheritance.
* WARNING: When used with inheritance, manual care must be taken to not invoke
* a parent initializer twice, or ensure that all initializers are idempotent,
* because this is not dealt with automatically as with constructors.
*/
contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
*/
bool private initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private initializing;
/**
* @dev Modifier to use in the initializer function of a contract.
*/
modifier initializer() {
require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized");
bool wasInitializing = initializing;
initializing = true;
initialized = true;
_;
initializing = wasInitializing;
}
/// @dev Returns true if and only if the function is running in the constructor
function isConstructor() private view returns (bool) {
// extcodesize checks the size of the code stored in an address, and
// address returns the current address. Since the code is still not
// deployed when running a constructor, any checks on its code size will
// yield zero, making it an effective way to detect if a contract is
// under construction or not.
uint256 cs;
assembly { cs := extcodesize(address) }
return cs == 0;
}
// Reserved storage space to allow for layout changes in the future.
uint256[50] private ______gap;
}
// File: openzeppelin-eth/contracts/math/SafeMath.sol
pragma solidity ^0.4.24;
/**
* @title SafeMath
* @dev Math operations with safety checks that revert on error
*/
library SafeMath {
/**
* @dev Multiplies two numbers, reverts on overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b);
return c;
}
/**
* @dev Integer division of two numbers truncating the quotient, reverts on division by zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0); // Solidity only automatically asserts when dividing by 0
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a);
uint256 c = a - b;
return c;
}
/**
* @dev Adds two numbers, reverts on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a);
return c;
}
/**
* @dev Divides two numbers and returns the remainder (unsigned integer modulo),
* reverts when dividing by zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0);
return a % b;
}
}
// File: minimetoken/contracts/TokenController.sol
pragma solidity ^0.4.18;
/// @dev The token controller contract must implement these functions
contract TokenController {
/// @notice Called when `_owner` sends ether to the MiniMe Token contract
/// @param _owner The address that sent the ether to create tokens
/// @return True if the ether is accepted, false if it throws
function proxyPayment(address _owner) public payable returns(bool);
/// @notice Notifies the controller about a token transfer allowing the
/// controller to react if desired
/// @param _from The origin of the transfer
/// @param _to The destination of the transfer
/// @param _amount The amount of the transfer
/// @return False if the controller does not authorize the transfer
function onTransfer(address _from, address _to, uint _amount) public returns(bool);
/// @notice Notifies the controller about an approval allowing the
/// controller to react if desired
/// @param _owner The address that calls `approve()`
/// @param _spender The spender in the `approve()` call
/// @param _amount The amount in the `approve()` call
/// @return False if the controller does not authorize the approval
function onApprove(address _owner, address _spender, uint _amount) public
returns(bool);
}
// File: contracts/interfaces/IERC677.sol
pragma solidity ^0.4.24;
interface IERC677 {
function transfer(address _to, uint256 _value) external returns (bool);
function transferFrom(address _from, address _to, uint256 _value) external returns (bool);
function approve(address _spender, uint256 _value) external returns (bool);
function permit(address _holder, address _spender, uint256 _nonce, uint256 _expiry, bool _allowed, uint8 _v, bytes32 _r, bytes32 _s) external;
}
// File: contracts/interfaces/ITokenBridge.sol
pragma solidity ^0.4.24;
interface ITokenBridge {
function relayTokens(IERC677 token, address _receiver, uint256 _value) external;
}
// File: contracts/tokens/WrappedPinakion.sol
/**
* https://contributing.kleros.io/smart-contract-workflow
* @authors: [@fnanni-0]
* @reviewers: [@unknownunknown1, @MerlinEgalite, @hbarcelos, @shalzz]
* @auditors: []
* @bounties: []
* @deployments: []
*/
pragma solidity ^0.4.24;
contract WrappedPinakion is Initializable {
using SafeMath for uint256;
/* Events */
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/* Storage */
mapping (address => uint256) private balances;
mapping (address => mapping (address => uint256)) public allowance;
/// @dev Total supply of the token. Equals the total xPinakion deposit into the contract.
uint256 public totalSupply;
/// @dev Name of the token.
string public name;
/// @dev Symbol of the token.
string public symbol;
/// @dev Number of decimals of the token.
uint8 public decimals;
/// @dev The token's controller.
address public controller;
/// @dev Pinakion on xDai to be wrapped. This token is upgradeable.
IERC677 public xPinakion;
/// @dev xDai Token Bridge. The Token Bridge is upgradeable.
ITokenBridge public tokenBridge;
/* Modifiers */
/// @dev Verifies that the sender has ability to modify controlled parameters.
modifier onlyController() {
require(controller == msg.sender, "The caller is not the controller.");
_;
}
/* Initializer */
/** @dev Constructor.
* @param _name for the wrapped Pinakion on the home chain.
* @param _symbol for wrapped Pinakion ticker on the home chain.
* @param _xPinakion the home pinakion contract which is already bridged to the foreign pinakion contract.
* @param _tokenBridge the TokenBridge contract.
*/
function initialize(
string memory _name,
string memory _symbol,
IERC677 _xPinakion,
ITokenBridge _tokenBridge
) public initializer {
name = _name;
symbol = _symbol;
decimals = 18;
xPinakion = _xPinakion;
tokenBridge = _tokenBridge;
controller = msg.sender;
}
/* External */
/** @dev Changes `controller` to `_controller`.
* @param _controller The new controller of the contract
*/
function changeController(address _controller) external onlyController {
controller = _controller;
}
/** @dev Converts bridged pinakions into pinakions which can be staked in KlerosLiquid.
* @param _amount The amount of wrapped pinakions to mint.
*/
function deposit(uint _amount) external {
_mint(msg.sender, _amount);
require(xPinakion.transferFrom(msg.sender, address(this), _amount), "Sender does not have enough approved funds.");
}
/** @dev IERC20 Receiver functionality.
* Converts bridged PNK (xPinakion) into wrapped PNK which can be staked in KlerosLiquid.
* If the tokenBridge is calling this function, then this contract has already received
* the xPinakion tokens.
* @param _token The token address the _amount belongs to.
* @param _amount The amount of wrapped pinakions to mint.
* @param _data Calldata containing the address of the recipient.
*/
function onTokenBridged(address _token, uint _amount, bytes _data) external {
require(msg.sender == address(tokenBridge), "Sender not authorized.");
require(_token == address(xPinakion), "Token bridged is not xPinakion.");
address recipient;
assembly {
recipient := calldataload(0x84)
}
_mint(recipient, _amount);
}
/** @dev Withdraws bridged pinakions.
* @param _amount The amount of bridged pinakions to withdraw.
*/
function withdraw(uint _amount) external {
_burn(_amount);
require(xPinakion.transfer(msg.sender, _amount), "The `transfer` function must not fail.");
}
/** @dev This function is not strictly needed, but it provides a good UX to users who want to get their Mainnet's PNK back.
* What normally takes 3 transactions, here is done in one go.
* Notice that the PNK have to be claimed on mainnet's TokenBride by the receiver.
* @param _amount The amount of bridged pinakions to withdraw.
* @param _receiver The address which will receive the PNK back in the foreign chain.
*/
function withdrawAndConvertToPNK(uint _amount, address _receiver) external {
_burn(_amount);
// Using approve is safe here, because this contract approves the bridge to spend the tokens and triggers the relay immediately.
xPinakion.approve(address(tokenBridge), _amount);
tokenBridge.relayTokens(xPinakion, _receiver, _amount);
}
/** @dev Moves `_amount` tokens from the caller's account to `_recipient`.
* @param _recipient The entity receiving the funds.
* @param _amount The amount to tranfer in base units.
*/
function transfer(address _recipient, uint256 _amount) public returns (bool) {
if (isContract(controller)) {
require(TokenController(controller).onTransfer(msg.sender, _recipient, _amount));
}
balances[msg.sender] = balances[msg.sender].sub(_amount); // ERC20: transfer amount exceeds balance
balances[_recipient] = balances[_recipient].add(_amount);
emit Transfer(msg.sender, _recipient, _amount);
return true;
}
/** @dev Moves `_amount` tokens from `_sender` to `_recipient` using the
* allowance mechanism. `_amount` is then deducted from the caller's allowance.
* @param _sender The entity to take the funds from.
* @param _recipient The entity receiving the funds.
* @param _amount The amount to tranfer in base units.
*/
function transferFrom(address _sender, address _recipient, uint256 _amount) public returns (bool) {
if (isContract(controller)) {
require(TokenController(controller).onTransfer(_sender, _recipient, _amount));
}
/** The controller of this contract can move tokens around at will,
* this is important to recognize! Confirm that you trust the
* controller of this contract, which in most situations should be
* another open source smart contract or 0x0.
*/
if (msg.sender != controller) {
allowance[_sender][msg.sender] = allowance[_sender][msg.sender].sub(_amount); // ERC20: transfer amount exceeds allowance.
}
balances[_sender] = balances[_sender].sub(_amount); // ERC20: transfer amount exceeds balance
balances[_recipient] = balances[_recipient].add(_amount);
emit Transfer(_sender, _recipient, _amount);
return true;
}
/** @dev Approves `_spender` to spend `_amount`.
* @param _spender The entity allowed to spend funds.
* @param _amount The amount of base units the entity will be allowed to spend.
*/
function approve(address _spender, uint256 _amount) public returns (bool) {
// Alerts the token controller of the approve function call
if (isContract(controller)) {
require(TokenController(controller).onApprove(msg.sender, _spender, _amount), "Token controller does not approve.");
}
allowance[msg.sender][_spender] = _amount;
emit Approval(msg.sender, _spender, _amount);
return true;
}
/** @dev Increases the `_spender` allowance by `_addedValue`.
* @param _spender The entity allowed to spend funds.
* @param _addedValue The amount of extra base units the entity will be allowed to spend.
*/
function increaseAllowance(address _spender, uint256 _addedValue) public returns (bool) {
uint256 newAllowance = allowance[msg.sender][_spender].add(_addedValue);
// Alerts the token controller of the approve function call
if (isContract(controller)) {
require(TokenController(controller).onApprove(msg.sender, _spender, newAllowance), "Token controller does not approve.");
}
allowance[msg.sender][_spender] = newAllowance;
emit Approval(msg.sender, _spender, newAllowance);
return true;
}
/** @dev Decreases the `_spender` allowance by `_subtractedValue`.
* @param _spender The entity whose spending allocation will be reduced.
* @param _subtractedValue The reduction of spending allocation in base units.
*/
function decreaseAllowance(address _spender, uint256 _subtractedValue) public returns (bool) {
uint256 newAllowance = allowance[msg.sender][_spender].sub(_subtractedValue); // ERC20: decreased allowance below zero
// Alerts the token controller of the approve function call
if (isContract(controller)) {
require(TokenController(controller).onApprove(msg.sender, _spender, newAllowance), "Token controller does not approve.");
}
allowance[msg.sender][_spender] = newAllowance;
emit Approval(msg.sender, _spender, newAllowance);
return true;
}
/* Internal */
/**
* @dev Internal function that mints an amount of the token and assigns it to
* an account. This encapsulates the modification of balances such that the
* proper events are emitted.
* @param _recipient The amount that will be created.
* @param _amount The amount that will be created.
*/
function _mint(address _recipient, uint256 _amount) internal {
totalSupply = totalSupply.add(_amount);
balances[_recipient] = balances[_recipient].add(_amount);
emit Transfer(address(0x0), _recipient, _amount);
}
/** @dev Destroys `_amount` tokens from the caller. Cannot burn locked tokens.
* @param _amount The quantity of tokens to burn in base units.
*/
function _burn(uint256 _amount) internal {
if (isContract(controller)) {
require(TokenController(controller).onTransfer(msg.sender, address(0x0), _amount));
}
balances[msg.sender] = balances[msg.sender].sub(_amount); // ERC20: burn amount exceeds balance
totalSupply = totalSupply.sub(_amount);
emit Transfer(msg.sender, address(0x0), _amount);
}
/** @dev Internal function to determine if an address is a contract.
* @param _addr The address being queried.
* @return True if `_addr` is a contract.
*/
function isContract(address _addr) internal view returns(bool) {
uint size;
if (_addr == 0) return false;
assembly {
size := extcodesize(_addr)
}
return size > 0;
}
/* Getters */
/**
* @dev Gets the balance of the specified address.
* @param _owner The address to query the balance of.
* @return uint256 value representing the amount owned by the passed address.
*/
function balanceOf(address _owner) public view returns (uint256) {
return balances[_owner];
}
}
Contract ABI
[{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"string","name":""}],"name":"name","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":""}],"name":"approve","inputs":[{"type":"address","name":"_spender"},{"type":"uint256","name":"_amount"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"totalSupply","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":""}],"name":"transferFrom","inputs":[{"type":"address","name":"_sender"},{"type":"address","name":"_recipient"},{"type":"uint256","name":"_amount"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"withdraw","inputs":[{"type":"uint256","name":"_amount"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint8","name":""}],"name":"decimals","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"xPinakion","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":""}],"name":"increaseAllowance","inputs":[{"type":"address","name":"_spender"},{"type":"uint256","name":"_addedValue"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"changeController","inputs":[{"type":"address","name":"_controller"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"balanceOf","inputs":[{"type":"address","name":"_owner"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"withdrawAndConvertToPNK","inputs":[{"type":"uint256","name":"_amount"},{"type":"address","name":"_receiver"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"initialize","inputs":[{"type":"string","name":"_name"},{"type":"string","name":"_symbol"},{"type":"address","name":"_xPinakion"},{"type":"address","name":"_tokenBridge"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"string","name":""}],"name":"symbol","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":""}],"name":"decreaseAllowance","inputs":[{"type":"address","name":"_spender"},{"type":"uint256","name":"_subtractedValue"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":""}],"name":"transfer","inputs":[{"type":"address","name":"_recipient"},{"type":"uint256","name":"_amount"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"deposit","inputs":[{"type":"uint256","name":"_amount"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"tokenBridge","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"onTokenBridged","inputs":[{"type":"address","name":"_token"},{"type":"uint256","name":"_amount"},{"type":"bytes","name":"_data"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"allowance","inputs":[{"type":"address","name":""},{"type":"address","name":""}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"controller","inputs":[],"constant":true},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","indexed":true},{"type":"address","name":"to","indexed":true},{"type":"uint256","name":"value","indexed":false}],"anonymous":false},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"owner","indexed":true},{"type":"address","name":"spender","indexed":true},{"type":"uint256","name":"value","indexed":false}],"anonymous":false}]
Contract Creation Code
0x608060405234801561001057600080fd5b50611574806100206000396000f3006080604052600436106100f85763ffffffff60e060020a60003504166306fdde0381146100fd578063095ea7b31461018757806318160ddd146101bf57806323b872dd146101e65780632e1a7d4d14610210578063313ce5671461022a57806333e1cbda1461025557806339509351146102865780633cebb823146102aa57806370a08231146102cb5780638108022d146102ec5780638f15b4141461031057806395d89b41146103bd578063a457c2d7146103d2578063a9059cbb146103f6578063b6b55f251461041a578063c6328a4614610432578063db7af85414610447578063dd62ed3e14610478578063f77c47911461049f575b600080fd5b34801561010957600080fd5b506101126104b4565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561014c578181015183820152602001610134565b50505050905090810190601f1680156101795780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561019357600080fd5b506101ab600160a060020a0360043516602435610542565b604080519115158252519081900360200190f35b3480156101cb57600080fd5b506101d461069c565b60408051918252519081900360200190f35b3480156101f257600080fd5b506101ab600160a060020a03600435811690602435166044356106a2565b34801561021c57600080fd5b5061022860043561087f565b005b34801561023657600080fd5b5061023f610976565b6040805160ff9092168252519081900360200190f35b34801561026157600080fd5b5061026a61097f565b60408051600160a060020a039092168252519081900360200190f35b34801561029257600080fd5b506101ab600160a060020a036004351660243561098e565b3480156102b657600080fd5b50610228600160a060020a0360043516610b1f565b3480156102d757600080fd5b506101d4600160a060020a0360043516610bbb565b3480156102f857600080fd5b50610228600435600160a060020a0360243516610bd6565b34801561031c57600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261022894369492936024939284019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375094975050600160a060020a038535811696506020909501359094169350610ce692505050565b3480156103c957600080fd5b50610112610e39565b3480156103de57600080fd5b506101ab600160a060020a0360043516602435610e94565b34801561040257600080fd5b506101ab600160a060020a0360043516602435610eca565b34801561042657600080fd5b50610228600435611026565b34801561043e57600080fd5b5061026a611126565b34801561045357600080fd5b5061022860048035600160a060020a0316906024803591604435918201910135611135565b34801561048457600080fd5b506101d4600160a060020a0360043581169060243516611210565b3480156104ab57600080fd5b5061026a61122d565b6036805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561053a5780601f1061050f5761010080835404028352916020019161053a565b820191906000526020600020905b81548152906001019060200180831161051d57829003601f168201915b505050505081565b60385460009061055f906101009004600160a060020a0316611241565b15610647576038546040805160e060020a63da682aeb028152336004820152600160a060020a0386811660248301526044820186905291516101009093049091169163da682aeb916064808201926020929091908290030181600087803b1580156105c957600080fd5b505af11580156105dd573d6000803e3d6000fd5b505050506040513d60208110156105f357600080fd5b50511515610647576040805160e560020a62461bcd02815260206004820152602260248201526000805160206114e9833981519152604482015260f160020a61329702606482015290519081900360840190fd5b336000818152603460209081526040808320600160a060020a0388168085529083529281902086905580518681529051929392600080516020611529833981519152929181900390910190a350600192915050565b60355481565b6038546000906106bf906101009004600160a060020a0316611241565b15610762576038546040805160e060020a634a393149028152600160a060020a038781166004830152868116602483015260448201869052915161010090930490911691634a393149916064808201926020929091908290030181600087803b15801561072b57600080fd5b505af115801561073f573d6000803e3d6000fd5b505050506040513d602081101561075557600080fd5b5051151561076257600080fd5b6038546101009004600160a060020a031633146107d257600160a060020a03841660009081526034602090815260408083203384529091529020546107ad908363ffffffff61126e16565b600160a060020a03851660009081526034602090815260408083203384529091529020555b600160a060020a0384166000908152603360205260409020546107fb908363ffffffff61126e16565b600160a060020a038086166000908152603360205260408082209390935590851681522054610830908363ffffffff61128516565b600160a060020a03808516600081815260336020908152604091829020949094558051868152905191939288169260008051602061150983398151915292918290030190a35060019392505050565b6108888161129e565b6039546040805160e060020a63a9059cbb028152336004820152602481018490529051600160a060020a039092169163a9059cbb916044808201926020929091908290030181600087803b1580156108df57600080fd5b505af11580156108f3573d6000803e3d6000fd5b505050506040513d602081101561090957600080fd5b50511515610973576040805160e560020a62461bcd02815260206004820152602660248201527f54686520607472616e73666572602066756e6374696f6e206d757374206e6f74604482015260d160020a65103330b4b61702606482015290519081900360840190fd5b50565b60385460ff1681565b603954600160a060020a031681565b336000908152603460209081526040808320600160a060020a038616845290915281205481906109c4908463ffffffff61128516565b6038549091506109e1906101009004600160a060020a0316611241565b15610ac9576038546040805160e060020a63da682aeb028152336004820152600160a060020a0387811660248301526044820185905291516101009093049091169163da682aeb916064808201926020929091908290030181600087803b158015610a4b57600080fd5b505af1158015610a5f573d6000803e3d6000fd5b505050506040513d6020811015610a7557600080fd5b50511515610ac9576040805160e560020a62461bcd02815260206004820152602260248201526000805160206114e9833981519152604482015260f160020a61329702606482015290519081900360840190fd5b336000818152603460209081526040808320600160a060020a0389168085529083529281902085905580518581529051929392600080516020611529833981519152929181900390910190a35060019392505050565b6038546101009004600160a060020a03163314610b93576040805160e560020a62461bcd02815260206004820152602160248201527f5468652063616c6c6572206973206e6f742074686520636f6e74726f6c6c6572604482015260f960020a601702606482015290519081900360840190fd5b60388054600160a060020a039092166101000261010060a860020a0319909216919091179055565b600160a060020a031660009081526033602052604090205490565b610bdf8261129e565b603954603a546040805160e060020a63095ea7b3028152600160a060020a039283166004820152602481018690529051919092169163095ea7b39160448083019260209291908290030181600087803b158015610c3b57600080fd5b505af1158015610c4f573d6000803e3d6000fd5b505050506040513d6020811015610c6557600080fd5b5050603a546039546040805160e060020a63ad58bdd1028152600160a060020a0392831660048201528483166024820152604481018690529051919092169163ad58bdd191606480830192600092919082900301818387803b158015610cca57600080fd5b505af1158015610cde573d6000803e3d6000fd5b505050505050565b60008054610100900460ff1680610d005750610d006113c8565b80610d0e575060005460ff16155b1515610d7e576040805160e560020a62461bcd02815260206004820152602e60248201527f436f6e747261637420696e7374616e63652068617320616c72656164792062656044820152609260020a6d195b881a5b9a5d1a585b1a5e995902606482015290519081900360840190fd5b5060008054600161010061ff00198316811760ff191691909117909255855191900460ff1690610db5906036906020880190611457565b508351610dc9906037906020870190611457565b506038805460398054600160a060020a0319908116600160a060020a0397881617909155603a80549091169490951693909317909355601260ff199092169190911761010060a860020a031916610100338102919091179092556000805461ff0019169115159092021790555050565b6037805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561053a5780601f1061050f5761010080835404028352916020019161053a565b336000908152603460209081526040808320600160a060020a038616845290915281205481906109c4908463ffffffff61126e16565b603854600090610ee7906101009004600160a060020a0316611241565b15610f88576038546040805160e060020a634a393149028152336004820152600160a060020a03868116602483015260448201869052915161010090930490911691634a393149916064808201926020929091908290030181600087803b158015610f5157600080fd5b505af1158015610f65573d6000803e3d6000fd5b505050506040513d6020811015610f7b57600080fd5b50511515610f8857600080fd5b33600090815260336020526040902054610fa8908363ffffffff61126e16565b3360009081526033602052604080822092909255600160a060020a03851681522054610fda908363ffffffff61128516565b600160a060020a0384166000818152603360209081526040918290209390935580518581529051919233926000805160206115098339815191529281900390910190a350600192915050565b61103033826113d2565b6039546040805160e060020a6323b872dd028152336004820152306024820152604481018490529051600160a060020a03909216916323b872dd916064808201926020929091908290030181600087803b15801561108d57600080fd5b505af11580156110a1573d6000803e3d6000fd5b505050506040513d60208110156110b757600080fd5b50511515610973576040805160e560020a62461bcd02815260206004820152602b60248201527f53656e64657220646f6573206e6f74206861766520656e6f7567682061707072604482015260a960020a6a37bb32b210333ab732399702606482015290519081900360840190fd5b603a54600160a060020a031681565b603a54600090600160a060020a03163314611196576040805160e560020a62461bcd0281526020600482015260166024820152605160020a7529b2b73232b9103737ba1030baba3437b934bd32b21702604482015290519081900360640190fd5b603954600160a060020a038681169116146111fb576040805160e560020a62461bcd02815260206004820152601f60248201527f546f6b656e2062726964676564206973206e6f74207850696e616b696f6e2e00604482015290519081900360640190fd5b5060843561120981856113d2565b5050505050565b603460209081526000928352604080842090915290825290205481565b6038546101009004600160a060020a031681565b600080600160a060020a038316151561125d5760009150611268565b823b90506000811191505b50919050565b6000808383111561127e57600080fd5b5050900390565b60008282018381101561129757600080fd5b9392505050565b6038546112b8906101009004600160a060020a0316611241565b15611359576038546040805160e060020a634a393149028152336004820152600060248201819052604482018590529151610100909304600160a060020a031692634a39314992606480840193602093929083900390910190829087803b15801561132257600080fd5b505af1158015611336573d6000803e3d6000fd5b505050506040513d602081101561134c57600080fd5b5051151561135957600080fd5b33600090815260336020526040902054611379908263ffffffff61126e16565b3360009081526033602052604090205560355461139c908263ffffffff61126e16565b60355560408051828152905160009133916000805160206115098339815191529181900360200190a350565b303b8015905b5090565b6035546113e5908263ffffffff61128516565b603555600160a060020a038216600090815260336020526040902054611411908263ffffffff61128516565b600160a060020a03831660008181526033602090815260408083209490945583518581529351929391926000805160206115098339815191529281900390910190a35050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061149857805160ff19168380011785556114c5565b828001600101855582156114c5579182015b828111156114c55782518255916020019190600101906114aa565b506113ce926114e59250905b808211156113ce57600081556001016114d1565b905600546f6b656e20636f6e74726f6c6c657220646f6573206e6f7420617070726f76ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925a165627a7a723058201587f87863e1c5003d96e0c41e7261fd6959542b51393190aac915590295acb20029
Deployed ByteCode
0x6080604052600436106100f85763ffffffff60e060020a60003504166306fdde0381146100fd578063095ea7b31461018757806318160ddd146101bf57806323b872dd146101e65780632e1a7d4d14610210578063313ce5671461022a57806333e1cbda1461025557806339509351146102865780633cebb823146102aa57806370a08231146102cb5780638108022d146102ec5780638f15b4141461031057806395d89b41146103bd578063a457c2d7146103d2578063a9059cbb146103f6578063b6b55f251461041a578063c6328a4614610432578063db7af85414610447578063dd62ed3e14610478578063f77c47911461049f575b600080fd5b34801561010957600080fd5b506101126104b4565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561014c578181015183820152602001610134565b50505050905090810190601f1680156101795780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561019357600080fd5b506101ab600160a060020a0360043516602435610542565b604080519115158252519081900360200190f35b3480156101cb57600080fd5b506101d461069c565b60408051918252519081900360200190f35b3480156101f257600080fd5b506101ab600160a060020a03600435811690602435166044356106a2565b34801561021c57600080fd5b5061022860043561087f565b005b34801561023657600080fd5b5061023f610976565b6040805160ff9092168252519081900360200190f35b34801561026157600080fd5b5061026a61097f565b60408051600160a060020a039092168252519081900360200190f35b34801561029257600080fd5b506101ab600160a060020a036004351660243561098e565b3480156102b657600080fd5b50610228600160a060020a0360043516610b1f565b3480156102d757600080fd5b506101d4600160a060020a0360043516610bbb565b3480156102f857600080fd5b50610228600435600160a060020a0360243516610bd6565b34801561031c57600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261022894369492936024939284019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375094975050600160a060020a038535811696506020909501359094169350610ce692505050565b3480156103c957600080fd5b50610112610e39565b3480156103de57600080fd5b506101ab600160a060020a0360043516602435610e94565b34801561040257600080fd5b506101ab600160a060020a0360043516602435610eca565b34801561042657600080fd5b50610228600435611026565b34801561043e57600080fd5b5061026a611126565b34801561045357600080fd5b5061022860048035600160a060020a0316906024803591604435918201910135611135565b34801561048457600080fd5b506101d4600160a060020a0360043581169060243516611210565b3480156104ab57600080fd5b5061026a61122d565b6036805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561053a5780601f1061050f5761010080835404028352916020019161053a565b820191906000526020600020905b81548152906001019060200180831161051d57829003601f168201915b505050505081565b60385460009061055f906101009004600160a060020a0316611241565b15610647576038546040805160e060020a63da682aeb028152336004820152600160a060020a0386811660248301526044820186905291516101009093049091169163da682aeb916064808201926020929091908290030181600087803b1580156105c957600080fd5b505af11580156105dd573d6000803e3d6000fd5b505050506040513d60208110156105f357600080fd5b50511515610647576040805160e560020a62461bcd02815260206004820152602260248201526000805160206114e9833981519152604482015260f160020a61329702606482015290519081900360840190fd5b336000818152603460209081526040808320600160a060020a0388168085529083529281902086905580518681529051929392600080516020611529833981519152929181900390910190a350600192915050565b60355481565b6038546000906106bf906101009004600160a060020a0316611241565b15610762576038546040805160e060020a634a393149028152600160a060020a038781166004830152868116602483015260448201869052915161010090930490911691634a393149916064808201926020929091908290030181600087803b15801561072b57600080fd5b505af115801561073f573d6000803e3d6000fd5b505050506040513d602081101561075557600080fd5b5051151561076257600080fd5b6038546101009004600160a060020a031633146107d257600160a060020a03841660009081526034602090815260408083203384529091529020546107ad908363ffffffff61126e16565b600160a060020a03851660009081526034602090815260408083203384529091529020555b600160a060020a0384166000908152603360205260409020546107fb908363ffffffff61126e16565b600160a060020a038086166000908152603360205260408082209390935590851681522054610830908363ffffffff61128516565b600160a060020a03808516600081815260336020908152604091829020949094558051868152905191939288169260008051602061150983398151915292918290030190a35060019392505050565b6108888161129e565b6039546040805160e060020a63a9059cbb028152336004820152602481018490529051600160a060020a039092169163a9059cbb916044808201926020929091908290030181600087803b1580156108df57600080fd5b505af11580156108f3573d6000803e3d6000fd5b505050506040513d602081101561090957600080fd5b50511515610973576040805160e560020a62461bcd02815260206004820152602660248201527f54686520607472616e73666572602066756e6374696f6e206d757374206e6f74604482015260d160020a65103330b4b61702606482015290519081900360840190fd5b50565b60385460ff1681565b603954600160a060020a031681565b336000908152603460209081526040808320600160a060020a038616845290915281205481906109c4908463ffffffff61128516565b6038549091506109e1906101009004600160a060020a0316611241565b15610ac9576038546040805160e060020a63da682aeb028152336004820152600160a060020a0387811660248301526044820185905291516101009093049091169163da682aeb916064808201926020929091908290030181600087803b158015610a4b57600080fd5b505af1158015610a5f573d6000803e3d6000fd5b505050506040513d6020811015610a7557600080fd5b50511515610ac9576040805160e560020a62461bcd02815260206004820152602260248201526000805160206114e9833981519152604482015260f160020a61329702606482015290519081900360840190fd5b336000818152603460209081526040808320600160a060020a0389168085529083529281902085905580518581529051929392600080516020611529833981519152929181900390910190a35060019392505050565b6038546101009004600160a060020a03163314610b93576040805160e560020a62461bcd02815260206004820152602160248201527f5468652063616c6c6572206973206e6f742074686520636f6e74726f6c6c6572604482015260f960020a601702606482015290519081900360840190fd5b60388054600160a060020a039092166101000261010060a860020a0319909216919091179055565b600160a060020a031660009081526033602052604090205490565b610bdf8261129e565b603954603a546040805160e060020a63095ea7b3028152600160a060020a039283166004820152602481018690529051919092169163095ea7b39160448083019260209291908290030181600087803b158015610c3b57600080fd5b505af1158015610c4f573d6000803e3d6000fd5b505050506040513d6020811015610c6557600080fd5b5050603a546039546040805160e060020a63ad58bdd1028152600160a060020a0392831660048201528483166024820152604481018690529051919092169163ad58bdd191606480830192600092919082900301818387803b158015610cca57600080fd5b505af1158015610cde573d6000803e3d6000fd5b505050505050565b60008054610100900460ff1680610d005750610d006113c8565b80610d0e575060005460ff16155b1515610d7e576040805160e560020a62461bcd02815260206004820152602e60248201527f436f6e747261637420696e7374616e63652068617320616c72656164792062656044820152609260020a6d195b881a5b9a5d1a585b1a5e995902606482015290519081900360840190fd5b5060008054600161010061ff00198316811760ff191691909117909255855191900460ff1690610db5906036906020880190611457565b508351610dc9906037906020870190611457565b506038805460398054600160a060020a0319908116600160a060020a0397881617909155603a80549091169490951693909317909355601260ff199092169190911761010060a860020a031916610100338102919091179092556000805461ff0019169115159092021790555050565b6037805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561053a5780601f1061050f5761010080835404028352916020019161053a565b336000908152603460209081526040808320600160a060020a038616845290915281205481906109c4908463ffffffff61126e16565b603854600090610ee7906101009004600160a060020a0316611241565b15610f88576038546040805160e060020a634a393149028152336004820152600160a060020a03868116602483015260448201869052915161010090930490911691634a393149916064808201926020929091908290030181600087803b158015610f5157600080fd5b505af1158015610f65573d6000803e3d6000fd5b505050506040513d6020811015610f7b57600080fd5b50511515610f8857600080fd5b33600090815260336020526040902054610fa8908363ffffffff61126e16565b3360009081526033602052604080822092909255600160a060020a03851681522054610fda908363ffffffff61128516565b600160a060020a0384166000818152603360209081526040918290209390935580518581529051919233926000805160206115098339815191529281900390910190a350600192915050565b61103033826113d2565b6039546040805160e060020a6323b872dd028152336004820152306024820152604481018490529051600160a060020a03909216916323b872dd916064808201926020929091908290030181600087803b15801561108d57600080fd5b505af11580156110a1573d6000803e3d6000fd5b505050506040513d60208110156110b757600080fd5b50511515610973576040805160e560020a62461bcd02815260206004820152602b60248201527f53656e64657220646f6573206e6f74206861766520656e6f7567682061707072604482015260a960020a6a37bb32b210333ab732399702606482015290519081900360840190fd5b603a54600160a060020a031681565b603a54600090600160a060020a03163314611196576040805160e560020a62461bcd0281526020600482015260166024820152605160020a7529b2b73232b9103737ba1030baba3437b934bd32b21702604482015290519081900360640190fd5b603954600160a060020a038681169116146111fb576040805160e560020a62461bcd02815260206004820152601f60248201527f546f6b656e2062726964676564206973206e6f74207850696e616b696f6e2e00604482015290519081900360640190fd5b5060843561120981856113d2565b5050505050565b603460209081526000928352604080842090915290825290205481565b6038546101009004600160a060020a031681565b600080600160a060020a038316151561125d5760009150611268565b823b90506000811191505b50919050565b6000808383111561127e57600080fd5b5050900390565b60008282018381101561129757600080fd5b9392505050565b6038546112b8906101009004600160a060020a0316611241565b15611359576038546040805160e060020a634a393149028152336004820152600060248201819052604482018590529151610100909304600160a060020a031692634a39314992606480840193602093929083900390910190829087803b15801561132257600080fd5b505af1158015611336573d6000803e3d6000fd5b505050506040513d602081101561134c57600080fd5b5051151561135957600080fd5b33600090815260336020526040902054611379908263ffffffff61126e16565b3360009081526033602052604090205560355461139c908263ffffffff61126e16565b60355560408051828152905160009133916000805160206115098339815191529181900360200190a350565b303b8015905b5090565b6035546113e5908263ffffffff61128516565b603555600160a060020a038216600090815260336020526040902054611411908263ffffffff61128516565b600160a060020a03831660008181526033602090815260408083209490945583518581529351929391926000805160206115098339815191529281900390910190a35050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061149857805160ff19168380011785556114c5565b828001600101855582156114c5579182015b828111156114c55782518255916020019190600101906114aa565b506113ce926114e59250905b808211156113ce57600081556001016114d1565b905600546f6b656e20636f6e74726f6c6c657220646f6573206e6f7420617070726f76ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925a165627a7a723058201587f87863e1c5003d96e0c41e7261fd6959542b51393190aac915590295acb20029