Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- BPGToken
- Optimization enabled
- false
- Compiler version
- v0.8.28+commit.7893614a
- EVM Version
- shanghai
- Verified at
- 2024-12-29T14:20:07.016263Z
Contract source code
// File: bitpost-contracts/contracts-common/interfaces/upgrade/IInitializable.sol
pragma solidity ^0.8.20;
interface IInitializable {
error InitializableAlreadyInitialized();
error InitializableRequiredVersion(uint256 currentVersion, uint256 requiredVersion);
error InitializableMinimalVersion(uint256 currentVersion, uint256 minimalVersion);
function getVersion() external view returns(uint256);
}
// File: bitpost-contracts/contracts-common/contracts/upgrade/Initializable.sol
pragma solidity ^0.8.20;
abstract contract Initializable is IInitializable {
/// @custom:storage-location erc7201:bitpost.common.Initializable
struct Storage_Initializable {
uint256 version;
}
// keccak256(abi.encode(uint256(keccak256("bitpost.common.Initializable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant STORAGE_LOCATION_INITIALIZABLE = 0xf9388d16ccb89f8ceeb8bce5074db391472ebb34229a1051e19fc642d992d400;
modifier initVer(uint256 version) {
Storage_Initializable storage $ = _getStorage_Initializable();
require($.version == 0, InitializableAlreadyInitialized());
_;
$.version = version;
}
modifier upVer(uint256 version) {
Storage_Initializable storage $ = _getStorage_Initializable();
require($.version == version - 1, InitializableRequiredVersion($.version, version - 1));
_;
$.version = version;
}
modifier minVer(uint256 version) {
_checkMinVer(version);
_;
}
function getVersion() public view returns(uint256) {
Storage_Initializable storage $ = _getStorage_Initializable();
return $.version;
}
function _checkMinVer(uint256 version) private view {
Storage_Initializable storage $ = _getStorage_Initializable();
require($.version >= version, InitializableMinimalVersion($.version, version));
}
function _getStorage_Initializable() private pure returns(Storage_Initializable storage $) {
assembly {
$.slot := STORAGE_LOCATION_INITIALIZABLE
}
}
}
// File: bitpost-contracts/contracts-common/interfaces/access/IOwnable.sol
pragma solidity ^0.8.20;
interface IOwnable {
error OwnableUnauthorized(address sender, address owner);
error OwnableInvalidOwner(address owner);
function getOwner() external view returns(address);
function setOwner(address owner) external;
}
// File: bitpost-contracts/contracts-common/contracts/access/Ownable.sol
pragma solidity ^0.8.20;
abstract contract Ownable is IOwnable {
/// @custom:storage-location erc7201:bitpost.common.Ownable
struct Storage_Ownable {
address owner;
}
// keccak256(abi.encode(uint256(keccak256("bitpost.common.Ownable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant STORAGE_LOCATION_OWNABLE = 0xbfdc26bbaea09886fc184fe4fcae59b15cffdf4b859be87d5955dbd541465600;
modifier onlyOwner() {
_checkOwner();
_;
}
function _init_Ownable(address owner) internal {
_setOwner(owner);
}
function getOwner() public view returns(address) {
Storage_Ownable storage $ = _getStorage_Ownable();
return $.owner;
}
function setOwner(address owner) external onlyOwner {
_setOwner(owner);
}
function _setOwner(address owner) internal {
require(owner != address(0), OwnableInvalidOwner(address(0)));
Storage_Ownable storage $ = _getStorage_Ownable();
$.owner = owner;
}
function _checkOwner() private view {
Storage_Ownable storage $ = _getStorage_Ownable();
require(msg.sender == $.owner, OwnableUnauthorized(msg.sender, $.owner));
}
function _getStorage_Ownable() private pure returns(Storage_Ownable storage $) {
assembly {
$.slot := STORAGE_LOCATION_OWNABLE
}
}
}
// File: bitpost-contracts/contracts-bpg/interfaces/erc20/IERC20.sol
pragma solidity ^0.8.20;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns(uint256);
function balanceOf(address account) external view returns(uint256);
function transfer(address to, uint256 value) external returns(bool);
function allowance(address owner, address spender) external view returns(uint256);
function approve(address spender, uint256 value) external returns(bool);
function transferFrom(address from, address to, uint256 value) external returns(bool);
}
// File: bitpost-contracts/contracts-bpg/interfaces/erc20/IERC20Errors.sol
pragma solidity ^0.8.20;
interface IERC20Errors is IERC20 {
error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
error ERC20InvalidSender(address sender);
error ERC20InvalidReceiver(address receiver);
error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
error ERC20InvalidApprover(address approver);
error ERC20InvalidSpender(address spender);
}
// File: bitpost-contracts/contracts-bpg/interfaces/erc20/IERC20Metadata.sol
pragma solidity ^0.8.20;
interface IERC20Metadata is IERC20 {
function name() external pure returns(string memory);
function symbol() external pure returns(string memory);
function decimals() external pure returns(uint8);
}
// File: bitpost-contracts/contracts-bpg/interfaces/history/IERC20History.sol
pragma solidity ^0.8.20;
interface IERC20History is IERC20 {
error ERC20HistoryInvalidBlockNumber(uint256 blockNumber);
function totalSupplyAt(uint256 blockNumber) external view returns(uint256);
function balanceOfAt(address account, uint256 blockNumber) external view returns(uint256);
}
// File: bitpost-contracts/contracts-bpg/interfaces/IBPGToken.sol
pragma solidity ^0.8.20;
interface IBPGToken is IInitializable, IOwnable, IERC20, IERC20Errors, IERC20Metadata, IERC20History {
function init() external;
function mint(address account, uint256 value) external;
function burn(uint256 value) external;
}
// File: bitpost-contracts/contracts-bpg/contracts/erc20/ERC20.sol
pragma solidity ^0.8.20;
abstract contract ERC20 is IERC20, IERC20Errors {
/// @custom:storage-location erc7201:bitpost.bpg.ERC20
struct Storage_ERC20 {
uint256 totalSupply;
mapping(address account => uint256) balances;
mapping(address account => mapping(address spender => uint256)) allowances;
}
// keccak256(abi.encode(uint256(keccak256("bitpost.bpg.ERC20")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant STORAGE_LOCATION_ERC20 = 0xee0c2d5357d88d54dd6bbaa1b1a8910354885f2b74606115c4d95c4c54785400;
function totalSupply() public view returns(uint256) {
Storage_ERC20 storage $ = _getStorage_ERC20();
return $.totalSupply;
}
function balanceOf(address account) public view returns(uint256) {
Storage_ERC20 storage $ = _getStorage_ERC20();
return $.balances[account];
}
function transfer(address to, uint256 value) external returns(bool) {
_transfer(msg.sender, to, value);
return true;
}
function allowance(address owner, address spender) public view returns(uint256) {
Storage_ERC20 storage $ = _getStorage_ERC20();
return $.allowances[owner][spender];
}
function approve(address spender, uint256 value) external returns(bool) {
_approve(msg.sender, spender, value, true);
return true;
}
function transferFrom(address from, address to, uint256 value) external returns(bool) {
_spendAllowance(from, msg.sender, value);
_transfer(from, to, value);
return true;
}
function _transfer(address from, address to, uint256 value) internal {
require(from != address(0), ERC20InvalidSender(address(0)));
require(to != address(0), ERC20InvalidReceiver(address(0)));
_update(from, to, value);
}
function _update(address from, address to, uint256 value) internal virtual {
Storage_ERC20 storage $ = _getStorage_ERC20();
if(from == address(0)) {
// Overflow check required: The rest of the code assumes that totalSupply never overflows
$.totalSupply += value;
} else {
uint256 fromBalance = $.balances[from];
require(fromBalance >= value, ERC20InsufficientBalance(from, fromBalance, value));
unchecked {
// Overflow not possible: value <= fromBalance <= totalSupply.
$.balances[from] = fromBalance - value;
}
}
if(to == address(0)) {
unchecked {
// Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
$.totalSupply -= value;
}
} else {
unchecked {
// Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
$.balances[to] += value;
}
}
emit Transfer(from, to, value);
}
function _mint(address account, uint256 value) internal {
require(account != address(0), ERC20InvalidReceiver(address(0)));
_update(address(0), account, value);
}
function _burn(address account, uint256 value) internal {
require(account != address(0), ERC20InvalidSender(address(0)));
_update(account, address(0), value);
}
function _approve(address owner, address spender, uint256 value, bool emitEvent) internal {
require(owner != address(0), ERC20InvalidApprover(address(0)));
require(spender != address(0), ERC20InvalidSpender(address(0)));
Storage_ERC20 storage $ = _getStorage_ERC20();
$.allowances[owner][spender] = value;
if(emitEvent) {
emit Approval(owner, spender, value);
}
}
function _spendAllowance(address owner, address spender, uint256 value) internal {
uint256 currentAllowance = allowance(owner, spender);
if(currentAllowance < type(uint256).max) {
require(currentAllowance >= value, ERC20InsufficientAllowance(spender, currentAllowance, value));
unchecked {
_approve(owner, spender, currentAllowance - value, false);
}
}
}
function _getStorage_ERC20() private pure returns(Storage_ERC20 storage $) {
assembly {
$.slot := STORAGE_LOCATION_ERC20
}
}
}
// File: bitpost-contracts/contracts-bpg/contracts/history/ERC20History.sol
pragma solidity ^0.8.20;
abstract contract ERC20History is ERC20, IERC20History {
struct Checkpoint {
uint256 blockNumber;
uint256 value;
}
/// @custom:storage-location erc7201:bitpost.bpg.ERC20History
struct Storage_ERC20History {
mapping(address => Checkpoint[]) balanceCheckpoints;
Checkpoint[] totalSupplyCheckpoints;
}
// keccak256(abi.encode(uint256(keccak256("bitpost.bpg.ERC20History")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant STORAGE_LOCATION_ERC20HISTORY = 0xfcefface2da381a8744d5670ea5451aa1e4c0f3577d2d8c35c85f1cd24665400;
function totalSupplyAt(uint256 blockNumber) external view returns(uint256) {
Storage_ERC20History storage $ = _getStorage_ERC20History();
return _getCheckpoint($.totalSupplyCheckpoints, blockNumber, totalSupply());
}
function balanceOfAt(address account, uint256 blockNumber) external view returns(uint256) {
Storage_ERC20History storage $ = _getStorage_ERC20History();
return _getCheckpoint($.balanceCheckpoints[account], blockNumber, balanceOf(account));
}
function _update(address from, address to, uint256 value) internal virtual override {
Storage_ERC20History storage $ = _getStorage_ERC20History();
if(from != address(0)) {
_maybeCreateCheckpoint($.balanceCheckpoints[from], balanceOf(from));
}
if(to != address(0)) {
_maybeCreateCheckpoint($.balanceCheckpoints[to], balanceOf(to));
}
_maybeCreateCheckpoint($.totalSupplyCheckpoints, totalSupply());
super._update(from, to, value);
}
function _maybeCreateCheckpoint(Checkpoint[] storage checkpoints, uint256 value) private {
uint256 length = checkpoints.length;
if(length == 0 || checkpoints[length - 1].blockNumber < block.number) {
checkpoints.push(Checkpoint({
blockNumber: block.number,
value: value
}));
}
}
function _getCheckpoint(Checkpoint[] storage checkpoints, uint256 blockNumber, uint256 currentValue) private view returns(uint256) {
require(blockNumber < block.number, ERC20HistoryInvalidBlockNumber(blockNumber));
uint256 high = checkpoints.length;
if(high == 0) {
return 0;
}
if(checkpoints[high - 1].blockNumber <= blockNumber) {
return currentValue;
}
uint256 low = 0;
while(low < high) {
uint256 mid = low + (high - low) / 2;
if(checkpoints[mid].blockNumber > blockNumber) {
high = mid;
} else {
unchecked {
low = mid + 1;
}
}
}
return checkpoints[low].value;
}
function _getStorage_ERC20History() private pure returns(Storage_ERC20History storage $) {
assembly {
$.slot := STORAGE_LOCATION_ERC20HISTORY
}
}
}
// File: bitpost-contracts/contracts-bpg/contracts/BPGToken.sol
pragma solidity ^0.8.20;
contract BPGToken is Initializable, Ownable, ERC20History, IBPGToken {
function init() external initVer(1) {
_init_Ownable(msg.sender);
}
function name() external pure returns(string memory) {
return "Bitpost";
}
function symbol() external pure returns(string memory) {
return "BPG";
}
function decimals() external pure returns(uint8) {
return 6;
}
function mint(address account, uint256 value) external onlyOwner {
_mint(account, value);
}
function burn(uint256 value) external onlyOwner {
_burn(msg.sender, value);
}
}
Contract ABI
[{"type":"error","name":"ERC20HistoryInvalidBlockNumber","inputs":[{"type":"uint256","name":"blockNumber","internalType":"uint256"}]},{"type":"error","name":"ERC20InsufficientAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"allowance","internalType":"uint256"},{"type":"uint256","name":"needed","internalType":"uint256"}]},{"type":"error","name":"ERC20InsufficientBalance","inputs":[{"type":"address","name":"sender","internalType":"address"},{"type":"uint256","name":"balance","internalType":"uint256"},{"type":"uint256","name":"needed","internalType":"uint256"}]},{"type":"error","name":"ERC20InvalidApprover","inputs":[{"type":"address","name":"approver","internalType":"address"}]},{"type":"error","name":"ERC20InvalidReceiver","inputs":[{"type":"address","name":"receiver","internalType":"address"}]},{"type":"error","name":"ERC20InvalidSender","inputs":[{"type":"address","name":"sender","internalType":"address"}]},{"type":"error","name":"ERC20InvalidSpender","inputs":[{"type":"address","name":"spender","internalType":"address"}]},{"type":"error","name":"InitializableAlreadyInitialized","inputs":[]},{"type":"error","name":"InitializableMinimalVersion","inputs":[{"type":"uint256","name":"currentVersion","internalType":"uint256"},{"type":"uint256","name":"minimalVersion","internalType":"uint256"}]},{"type":"error","name":"InitializableRequiredVersion","inputs":[{"type":"uint256","name":"currentVersion","internalType":"uint256"},{"type":"uint256","name":"requiredVersion","internalType":"uint256"}]},{"type":"error","name":"OwnableInvalidOwner","inputs":[{"type":"address","name":"owner","internalType":"address"}]},{"type":"error","name":"OwnableUnauthorized","inputs":[{"type":"address","name":"sender","internalType":"address"},{"type":"address","name":"owner","internalType":"address"}]},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"address","name":"spender","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"allowance","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"spender","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approve","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOfAt","inputs":[{"type":"address","name":"account","internalType":"address"},{"type":"uint256","name":"blockNumber","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"burn","inputs":[{"type":"uint256","name":"value","internalType":"uint256"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"getOwner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getVersion","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"init","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"mint","inputs":[{"type":"address","name":"account","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setOwner","inputs":[{"type":"address","name":"owner","internalType":"address"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupplyAt","inputs":[{"type":"uint256","name":"blockNumber","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferFrom","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"}]}]
Contract Creation Code
0x6080604052348015600e575f5ffd5b506117628061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610109575f3560e01c806342966c68116100a057806395d89b411161006f57806395d89b41146102b7578063981b24d0146102d5578063a9059cbb14610305578063dd62ed3e14610335578063e1c7392a1461036557610109565b806342966c681461021d5780634ee2cd7e1461023957806370a0823114610269578063893d20e81461029957610109565b806318160ddd116100dc57806318160ddd1461019557806323b872dd146101b3578063313ce567146101e357806340c10f191461020157610109565b806306fdde031461010d578063095ea7b31461012b5780630d8e6e2c1461015b57806313af403514610179575b5f5ffd5b61011561036f565b6040516101229190611329565b60405180910390f35b610145600480360381019061014091906113da565b6103ac565b6040516101529190611432565b60405180910390f35b6101636103c4565b604051610170919061145a565b60405180910390f35b610193600480360381019061018e9190611473565b6103da565b005b61019d6103ee565b6040516101aa919061145a565b60405180910390f35b6101cd60048036038101906101c8919061149e565b610404565b6040516101da9190611432565b60405180910390f35b6101eb610426565b6040516101f89190611509565b60405180910390f35b61021b600480360381019061021691906113da565b61042e565b005b61023760048036038101906102329190611522565b610444565b005b610253600480360381019061024e91906113da565b610459565b604051610260919061145a565b60405180910390f35b610283600480360381019061027e9190611473565b6104be565b604051610290919061145a565b60405180910390f35b6102a1610512565b6040516102ae919061155c565b60405180910390f35b6102bf610547565b6040516102cc9190611329565b60405180910390f35b6102ef60048036038101906102ea9190611522565b610584565b6040516102fc919061145a565b60405180910390f35b61031f600480360381019061031a91906113da565b6105ad565b60405161032c9190611432565b60405180910390f35b61034f600480360381019061034a9190611575565b6105c3565b60405161035c919061145a565b60405180910390f35b61036d610653565b005b60606040518060400160405280600781526020017f426974706f737400000000000000000000000000000000000000000000000000815250905090565b5f6103ba33848460016106b1565b6001905092915050565b5f5f6103ce610894565b9050805f015491505090565b6103e26108bb565b6103eb81610983565b50565b5f5f6103f8610a46565b9050805f015491505090565b5f610410843384610a6d565b61041b848484610b06565b600190509392505050565b5f6006905090565b6104366108bb565b6104408282610bfc565b5050565b61044c6108bb565b6104563382610c7e565b50565b5f5f610463610d00565b90506104b5815f015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20846104b0876104be565b610d27565b91505092915050565b5f5f6104c8610a46565b9050806001015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054915050919050565b5f5f61051c610e63565b9050805f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691505090565b60606040518060400160405280600381526020017f4250470000000000000000000000000000000000000000000000000000000000815250905090565b5f5f61058e610d00565b90506105a581600101846105a06103ee565b610d27565b915050919050565b5f6105b9338484610b06565b6001905092915050565b5f5f6105cd610a46565b9050806002015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205491505092915050565b60015f61065e610894565b90505f815f01541461069c576040517f0fe5ade500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106a533610e8a565b81815f01819055505050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614155f90610723576040517fe602df0500000000000000000000000000000000000000000000000000000000815260040161071a919061155c565b60405180910390fd5b505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155f90610796576040517f94280d6200000000000000000000000000000000000000000000000000000000815260040161078d919061155c565b60405180910390fd5b505f6107a0610a46565b905082816002015f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550811561088d578373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92585604051610884919061145a565b60405180910390a35b5050505050565b5f7ff9388d16ccb89f8ceeb8bce5074db391472ebb34229a1051e19fc642d992d400905090565b5f6108c4610e63565b9050805f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161433825f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16909161097e576040517f0992ea830000000000000000000000000000000000000000000000000000000081526004016109759291906115b3565b60405180910390fd5b505050565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155f906109f5576040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016109ec919061155c565b60405180910390fd5b505f6109ff610e63565b905081815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b5f7fee0c2d5357d88d54dd6bbaa1b1a8910354885f2b74606115c4d95c4c54785400905090565b5f610a7884846105c3565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811015610b005781811015838284909192610aee576040517ffb8f41b2000000000000000000000000000000000000000000000000000000008152600401610ae5939291906115da565b60405180910390fd5b505050610aff84848484035f6106b1565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155f90610b78576040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401610b6f919061155c565b60405180910390fd5b505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155f90610beb576040517fec442f05000000000000000000000000000000000000000000000000000000008152600401610be2919061155c565b60405180910390fd5b50610bf7838383610e96565b505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155f90610c6e576040517fec442f05000000000000000000000000000000000000000000000000000000008152600401610c65919061155c565b60405180910390fd5b50610c7a5f8383610e96565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155f90610cf0576040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401610ce7919061155c565b60405180910390fd5b50610cfc825f83610e96565b5050565b5f7ffcefface2da381a8744d5670ea5451aa1e4c0f3577d2d8c35c85f1cd24665400905090565b5f4383108390610d6d576040517f2ac61dc7000000000000000000000000000000000000000000000000000000008152600401610d64919061145a565b60405180910390fd5b505f848054905090505f8103610d86575f915050610e5c565b8385600183610d95919061163c565b81548110610da657610da561166f565b5b905f5260205f2090600202015f015411610dc35782915050610e5c565b5f5f90505b81811015610e34575f60028284610ddf919061163c565b610de991906116c9565b82610df491906116f9565b905085878281548110610e0a57610e0961166f565b5b905f5260205f2090600202015f01541115610e2757809250610e2e565b6001810191505b50610dc8565b858181548110610e4757610e4661166f565b5b905f5260205f20906002020160010154925050505b9392505050565b5f7fbfdc26bbaea09886fc184fe4fcae59b15cffdf4b859be87d5955dbd541465600905090565b610e9381610983565b50565b5f610e9f610d00565b90505f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614610f2457610f23815f015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20610f1e866104be565b610fcc565b5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614610fa757610fa6815f015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20610fa1856104be565b610fcc565b5b610fbb81600101610fb66103ee565b610fcc565b610fc6848484611069565b50505050565b5f828054905090505f81148061100e57504383600183610fec919061163c565b81548110610ffd57610ffc61166f565b5b905f5260205f2090600202015f0154105b156110645782604051806040016040528043815260200184815250908060018154018082558091505060019003905f5260205f2090600202015f909190919091505f820151815f01556020820151816001015550505b505050565b5f611072610a46565b90505f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036110c55781815f015f8282546110b991906116f9565b9250508190555061119f565b5f816001015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905082811015858285909192611154576040517fe450d38c00000000000000000000000000000000000000000000000000000000815260040161114b939291906115da565b60405180910390fd5b505050828103826001015f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036111e75781815f015f8282540392505081905550611234565b81816001015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611291919061145a565b60405180910390a350505050565b5f81519050919050565b5f82825260208201905092915050565b5f5b838110156112d65780820151818401526020810190506112bb565b5f8484015250505050565b5f601f19601f8301169050919050565b5f6112fb8261129f565b61130581856112a9565b93506113158185602086016112b9565b61131e816112e1565b840191505092915050565b5f6020820190508181035f83015261134181846112f1565b905092915050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6113768261134d565b9050919050565b6113868161136c565b8114611390575f5ffd5b50565b5f813590506113a18161137d565b92915050565b5f819050919050565b6113b9816113a7565b81146113c3575f5ffd5b50565b5f813590506113d4816113b0565b92915050565b5f5f604083850312156113f0576113ef611349565b5b5f6113fd85828601611393565b925050602061140e858286016113c6565b9150509250929050565b5f8115159050919050565b61142c81611418565b82525050565b5f6020820190506114455f830184611423565b92915050565b611454816113a7565b82525050565b5f60208201905061146d5f83018461144b565b92915050565b5f6020828403121561148857611487611349565b5b5f61149584828501611393565b91505092915050565b5f5f5f606084860312156114b5576114b4611349565b5b5f6114c286828701611393565b93505060206114d386828701611393565b92505060406114e4868287016113c6565b9150509250925092565b5f60ff82169050919050565b611503816114ee565b82525050565b5f60208201905061151c5f8301846114fa565b92915050565b5f6020828403121561153757611536611349565b5b5f611544848285016113c6565b91505092915050565b6115568161136c565b82525050565b5f60208201905061156f5f83018461154d565b92915050565b5f5f6040838503121561158b5761158a611349565b5b5f61159885828601611393565b92505060206115a985828601611393565b9150509250929050565b5f6040820190506115c65f83018561154d565b6115d3602083018461154d565b9392505050565b5f6060820190506115ed5f83018661154d565b6115fa602083018561144b565b611607604083018461144b565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f611646826113a7565b9150611651836113a7565b92508282039050818111156116695761166861160f565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6116d3826113a7565b91506116de836113a7565b9250826116ee576116ed61169c565b5b828204905092915050565b5f611703826113a7565b915061170e836113a7565b92508282019050808211156117265761172561160f565b5b9291505056fea2646970667358221220e257c187ab26a4c560b6fc461e1de47a36dd35d7e04eb1e547c6917fc7724a1764736f6c634300081c0033
Deployed ByteCode
0x608060405234801561000f575f5ffd5b5060043610610109575f3560e01c806342966c68116100a057806395d89b411161006f57806395d89b41146102b7578063981b24d0146102d5578063a9059cbb14610305578063dd62ed3e14610335578063e1c7392a1461036557610109565b806342966c681461021d5780634ee2cd7e1461023957806370a0823114610269578063893d20e81461029957610109565b806318160ddd116100dc57806318160ddd1461019557806323b872dd146101b3578063313ce567146101e357806340c10f191461020157610109565b806306fdde031461010d578063095ea7b31461012b5780630d8e6e2c1461015b57806313af403514610179575b5f5ffd5b61011561036f565b6040516101229190611329565b60405180910390f35b610145600480360381019061014091906113da565b6103ac565b6040516101529190611432565b60405180910390f35b6101636103c4565b604051610170919061145a565b60405180910390f35b610193600480360381019061018e9190611473565b6103da565b005b61019d6103ee565b6040516101aa919061145a565b60405180910390f35b6101cd60048036038101906101c8919061149e565b610404565b6040516101da9190611432565b60405180910390f35b6101eb610426565b6040516101f89190611509565b60405180910390f35b61021b600480360381019061021691906113da565b61042e565b005b61023760048036038101906102329190611522565b610444565b005b610253600480360381019061024e91906113da565b610459565b604051610260919061145a565b60405180910390f35b610283600480360381019061027e9190611473565b6104be565b604051610290919061145a565b60405180910390f35b6102a1610512565b6040516102ae919061155c565b60405180910390f35b6102bf610547565b6040516102cc9190611329565b60405180910390f35b6102ef60048036038101906102ea9190611522565b610584565b6040516102fc919061145a565b60405180910390f35b61031f600480360381019061031a91906113da565b6105ad565b60405161032c9190611432565b60405180910390f35b61034f600480360381019061034a9190611575565b6105c3565b60405161035c919061145a565b60405180910390f35b61036d610653565b005b60606040518060400160405280600781526020017f426974706f737400000000000000000000000000000000000000000000000000815250905090565b5f6103ba33848460016106b1565b6001905092915050565b5f5f6103ce610894565b9050805f015491505090565b6103e26108bb565b6103eb81610983565b50565b5f5f6103f8610a46565b9050805f015491505090565b5f610410843384610a6d565b61041b848484610b06565b600190509392505050565b5f6006905090565b6104366108bb565b6104408282610bfc565b5050565b61044c6108bb565b6104563382610c7e565b50565b5f5f610463610d00565b90506104b5815f015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20846104b0876104be565b610d27565b91505092915050565b5f5f6104c8610a46565b9050806001015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054915050919050565b5f5f61051c610e63565b9050805f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691505090565b60606040518060400160405280600381526020017f4250470000000000000000000000000000000000000000000000000000000000815250905090565b5f5f61058e610d00565b90506105a581600101846105a06103ee565b610d27565b915050919050565b5f6105b9338484610b06565b6001905092915050565b5f5f6105cd610a46565b9050806002015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205491505092915050565b60015f61065e610894565b90505f815f01541461069c576040517f0fe5ade500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106a533610e8a565b81815f01819055505050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614155f90610723576040517fe602df0500000000000000000000000000000000000000000000000000000000815260040161071a919061155c565b60405180910390fd5b505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155f90610796576040517f94280d6200000000000000000000000000000000000000000000000000000000815260040161078d919061155c565b60405180910390fd5b505f6107a0610a46565b905082816002015f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550811561088d578373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92585604051610884919061145a565b60405180910390a35b5050505050565b5f7ff9388d16ccb89f8ceeb8bce5074db391472ebb34229a1051e19fc642d992d400905090565b5f6108c4610e63565b9050805f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161433825f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16909161097e576040517f0992ea830000000000000000000000000000000000000000000000000000000081526004016109759291906115b3565b60405180910390fd5b505050565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155f906109f5576040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016109ec919061155c565b60405180910390fd5b505f6109ff610e63565b905081815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b5f7fee0c2d5357d88d54dd6bbaa1b1a8910354885f2b74606115c4d95c4c54785400905090565b5f610a7884846105c3565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811015610b005781811015838284909192610aee576040517ffb8f41b2000000000000000000000000000000000000000000000000000000008152600401610ae5939291906115da565b60405180910390fd5b505050610aff84848484035f6106b1565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155f90610b78576040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401610b6f919061155c565b60405180910390fd5b505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155f90610beb576040517fec442f05000000000000000000000000000000000000000000000000000000008152600401610be2919061155c565b60405180910390fd5b50610bf7838383610e96565b505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155f90610c6e576040517fec442f05000000000000000000000000000000000000000000000000000000008152600401610c65919061155c565b60405180910390fd5b50610c7a5f8383610e96565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155f90610cf0576040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401610ce7919061155c565b60405180910390fd5b50610cfc825f83610e96565b5050565b5f7ffcefface2da381a8744d5670ea5451aa1e4c0f3577d2d8c35c85f1cd24665400905090565b5f4383108390610d6d576040517f2ac61dc7000000000000000000000000000000000000000000000000000000008152600401610d64919061145a565b60405180910390fd5b505f848054905090505f8103610d86575f915050610e5c565b8385600183610d95919061163c565b81548110610da657610da561166f565b5b905f5260205f2090600202015f015411610dc35782915050610e5c565b5f5f90505b81811015610e34575f60028284610ddf919061163c565b610de991906116c9565b82610df491906116f9565b905085878281548110610e0a57610e0961166f565b5b905f5260205f2090600202015f01541115610e2757809250610e2e565b6001810191505b50610dc8565b858181548110610e4757610e4661166f565b5b905f5260205f20906002020160010154925050505b9392505050565b5f7fbfdc26bbaea09886fc184fe4fcae59b15cffdf4b859be87d5955dbd541465600905090565b610e9381610983565b50565b5f610e9f610d00565b90505f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614610f2457610f23815f015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20610f1e866104be565b610fcc565b5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614610fa757610fa6815f015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20610fa1856104be565b610fcc565b5b610fbb81600101610fb66103ee565b610fcc565b610fc6848484611069565b50505050565b5f828054905090505f81148061100e57504383600183610fec919061163c565b81548110610ffd57610ffc61166f565b5b905f5260205f2090600202015f0154105b156110645782604051806040016040528043815260200184815250908060018154018082558091505060019003905f5260205f2090600202015f909190919091505f820151815f01556020820151816001015550505b505050565b5f611072610a46565b90505f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036110c55781815f015f8282546110b991906116f9565b9250508190555061119f565b5f816001015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905082811015858285909192611154576040517fe450d38c00000000000000000000000000000000000000000000000000000000815260040161114b939291906115da565b60405180910390fd5b505050828103826001015f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036111e75781815f015f8282540392505081905550611234565b81816001015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611291919061145a565b60405180910390a350505050565b5f81519050919050565b5f82825260208201905092915050565b5f5b838110156112d65780820151818401526020810190506112bb565b5f8484015250505050565b5f601f19601f8301169050919050565b5f6112fb8261129f565b61130581856112a9565b93506113158185602086016112b9565b61131e816112e1565b840191505092915050565b5f6020820190508181035f83015261134181846112f1565b905092915050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6113768261134d565b9050919050565b6113868161136c565b8114611390575f5ffd5b50565b5f813590506113a18161137d565b92915050565b5f819050919050565b6113b9816113a7565b81146113c3575f5ffd5b50565b5f813590506113d4816113b0565b92915050565b5f5f604083850312156113f0576113ef611349565b5b5f6113fd85828601611393565b925050602061140e858286016113c6565b9150509250929050565b5f8115159050919050565b61142c81611418565b82525050565b5f6020820190506114455f830184611423565b92915050565b611454816113a7565b82525050565b5f60208201905061146d5f83018461144b565b92915050565b5f6020828403121561148857611487611349565b5b5f61149584828501611393565b91505092915050565b5f5f5f606084860312156114b5576114b4611349565b5b5f6114c286828701611393565b93505060206114d386828701611393565b92505060406114e4868287016113c6565b9150509250925092565b5f60ff82169050919050565b611503816114ee565b82525050565b5f60208201905061151c5f8301846114fa565b92915050565b5f6020828403121561153757611536611349565b5b5f611544848285016113c6565b91505092915050565b6115568161136c565b82525050565b5f60208201905061156f5f83018461154d565b92915050565b5f5f6040838503121561158b5761158a611349565b5b5f61159885828601611393565b92505060206115a985828601611393565b9150509250929050565b5f6040820190506115c65f83018561154d565b6115d3602083018461154d565b9392505050565b5f6060820190506115ed5f83018661154d565b6115fa602083018561144b565b611607604083018461144b565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f611646826113a7565b9150611651836113a7565b92508282039050818111156116695761166861160f565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6116d3826113a7565b91506116de836113a7565b9250826116ee576116ed61169c565b5b828204905092915050565b5f611703826113a7565b915061170e836113a7565b92508282019050808211156117265761172561160f565b5b9291505056fea2646970667358221220e257c187ab26a4c560b6fc461e1de47a36dd35d7e04eb1e547c6917fc7724a1764736f6c634300081c0033