Transactions
Token Transfers
Tokens
Internal Transactions
Coin Balance History
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.
- Contract name:
- PulseFinitySacrifice
- Optimization enabled
- true
- Compiler version
- v0.8.17+commit.8df45f5f
- Optimization runs
- 1000
- EVM Version
- default
- Verified at
- 2023-06-14T19:31:49.331573Z
Constructor Arguments
0xc2253742c2dec47d8d4914119e04236fe6faa3699644d694d50eeec56777621800000000000000000000000016e2adc9d0d898d3046e07dcf711dc1039a4857c00000000000000000000000000000000000000000047a2c828a48d2205a74c00000000000000000000000000537f63fa159832d99a7d8859264ce580b26601c2000000000000000000000000ea7b19c6c34c7e67cdc5a436b182f76d5a1442ee
Arg [0] (bytes32) : c2253742c2dec47d8d4914119e04236fe6faa3699644d694d50eeec567776218
Arg [1] (address) : 0x16e2adc9d0d898d3046e07dcf711dc1039a4857c
Arg [2] (uint256) : 86602448840299130800000000
Arg [3] (address) : 0x537f63fa159832d99a7d8859264ce580b26601c2
Arg [4] (address) : 0xea7b19c6c34c7e67cdc5a436b182f76d5a1442ee
contracts/src/PulseFinitySacrifice.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
import "../lib/MerkeProofVerifier.sol";
import "../interfaces/IPulseFinityToken.sol";
contract PulseFinitySacrifice is MerkleProofVerifier {
IPulseFinityToken public immutable pulseFinityToken;
// @notice The percentage allocations for the pulsefinity token supply
// @dev Percentage are in base 100
uint256 public immutable burnAllocation = 40_000;
uint256 public immutable priceDiscoveryAllocation = 1; // 0.0001%
uint256 public immutable teamAllocation = 3_000;
mapping(address => bool) public sacrificePointsClaimed;
event SacrificePointsClaimed(address indexed account, uint256 amount);
/// @dev The merkle root is the hash of the merkle tree of the sacrifice wallet
/// @dev addresses paired with their sacrifice points, One point is one token.
constructor(
bytes32 airdropMerkleRoot_,
address pulseFinityToken_,
uint256 sacrificePointsSupply_,
address teamAddress_,
address priceDiscoveryAddress_
) MerkleProofVerifier(airdropMerkleRoot_) {
require(pulseFinityToken_ != address(0), "PulseFinity token cannot be zero address");
require(sacrificePointsSupply_ != 0, "Sacrifice points supply cannot be zero");
require(teamAddress_ != address(0), "Team address cannot be zero address");
pulseFinityToken = IPulseFinityToken(pulseFinityToken_);
require(pulseFinityToken.totalSupply() > 0, "Token supply zero");
require(pulseFinityToken.balanceOf(address(this)) == pulseFinityToken.totalSupply(), "Supply distribution invalid");
uint256 pulseFinityTotalSupply = pulseFinityToken.totalSupply();
uint256 burnSupply = pulseFinityTotalSupply * burnAllocation / 100_000; // 20 billion
uint256 priceDiscoverySupply = pulseFinityTotalSupply * priceDiscoveryAllocation / 100_000; // 500k
uint256 teamSupply = pulseFinityTotalSupply * teamAllocation / 100_100; // 1.5 billion
uint256 sacrificePointsMaxSupply = pulseFinityTotalSupply - burnSupply - priceDiscoverySupply - teamSupply; // 13.5 billion
require(sacrificePointsMaxSupply + burnSupply + teamSupply + priceDiscoverySupply == pulseFinityToken.totalSupply(), "Invalid supply distribution");
require(sacrificePointsSupply_ <= sacrificePointsMaxSupply, "Sacrifice points supply cannot be greater than max supply");
pulseFinityToken.transfer(teamAddress_, teamSupply);
pulseFinityToken.transfer(priceDiscoveryAddress_, priceDiscoverySupply);
uint256 toBurn = pulseFinityToken.balanceOf(address(this)) - sacrificePointsSupply_;
if (toBurn > 0)
pulseFinityToken.burn(toBurn);
}
/// @notice Claim sacrifice points for a given address
function claimSacrificePoints(
address account,
uint256 amount,
bytes32[] calldata merkleProof
) external {
/// @dev Checks
require(account != address(0), "Account cannot be zero address");
require(amount != 0, "Amount cannot be zero");
require(!sacrificePointsClaimed[account], "Sacrifice points already claimed");
bytes32 leaf = keccak256(abi.encodePacked(account, amount));
verifyMerkleProof(leaf, merkleProof);
/// @dev Effects
sacrificePointsClaimed[account] = true;
/// @dev Interactions
pulseFinityToken.transfer(account, amount);
emit SacrificePointsClaimed(account, amount);
}
function receive() external payable {}
}
@openzeppelin/contracts/utils/cryptography/MerkleProof.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)
pragma solidity ^0.8.0;
/**
* @dev These functions deal with verification of Merkle Tree proofs.
*
* The proofs can be generated using the JavaScript library
* https://github.com/miguelmota/merkletreejs[merkletreejs].
* Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
*
* See `test/utils/cryptography/MerkleProof.test.js` for some examples.
*
* WARNING: You should avoid using leaf values that are 64 bytes long prior to
* hashing, or use a hash function other than keccak256 for hashing leaves.
* This is because the concatenation of a sorted pair of internal nodes in
* the merkle tree could be reinterpreted as a leaf value.
*/
library MerkleProof {
/**
* @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
* defined by `root`. For this, a `proof` must be provided, containing
* sibling hashes on the branch from the leaf to the root of the tree. Each
* pair of leaves and each pair of pre-images are assumed to be sorted.
*/
function verify(
bytes32[] memory proof,
bytes32 root,
bytes32 leaf
) internal pure returns (bool) {
return processProof(proof, leaf) == root;
}
/**
* @dev Calldata version of {verify}
*
* _Available since v4.7._
*/
function verifyCalldata(
bytes32[] calldata proof,
bytes32 root,
bytes32 leaf
) internal pure returns (bool) {
return processProofCalldata(proof, leaf) == root;
}
/**
* @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
* from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
* hash matches the root of the tree. When processing the proof, the pairs
* of leafs & pre-images are assumed to be sorted.
*
* _Available since v4.4._
*/
function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
computedHash = _hashPair(computedHash, proof[i]);
}
return computedHash;
}
/**
* @dev Calldata version of {processProof}
*
* _Available since v4.7._
*/
function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
computedHash = _hashPair(computedHash, proof[i]);
}
return computedHash;
}
/**
* @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by
* `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
*
* _Available since v4.7._
*/
function multiProofVerify(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32 root,
bytes32[] memory leaves
) internal pure returns (bool) {
return processMultiProof(proof, proofFlags, leaves) == root;
}
/**
* @dev Calldata version of {multiProofVerify}
*
* _Available since v4.7._
*/
function multiProofVerifyCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32 root,
bytes32[] memory leaves
) internal pure returns (bool) {
return processMultiProofCalldata(proof, proofFlags, leaves) == root;
}
/**
* @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`,
* consuming from one or the other at each step according to the instructions given by
* `proofFlags`.
*
* _Available since v4.7._
*/
function processMultiProof(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
// This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
// consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
// `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
// the merkle tree.
uint256 leavesLen = leaves.length;
uint256 totalHashes = proofFlags.length;
// Check proof validity.
require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");
// The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
// `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
bytes32[] memory hashes = new bytes32[](totalHashes);
uint256 leafPos = 0;
uint256 hashPos = 0;
uint256 proofPos = 0;
// At each step, we compute the next hash using two values:
// - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
// get the next hash.
// - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
// `proof` array.
for (uint256 i = 0; i < totalHashes; i++) {
bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
hashes[i] = _hashPair(a, b);
}
if (totalHashes > 0) {
return hashes[totalHashes - 1];
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
/**
* @dev Calldata version of {processMultiProof}
*
* _Available since v4.7._
*/
function processMultiProofCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
// This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
// consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
// `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
// the merkle tree.
uint256 leavesLen = leaves.length;
uint256 totalHashes = proofFlags.length;
// Check proof validity.
require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");
// The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
// `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
bytes32[] memory hashes = new bytes32[](totalHashes);
uint256 leafPos = 0;
uint256 hashPos = 0;
uint256 proofPos = 0;
// At each step, we compute the next hash using two values:
// - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
// get the next hash.
// - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
// `proof` array.
for (uint256 i = 0; i < totalHashes; i++) {
bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
hashes[i] = _hashPair(a, b);
}
if (totalHashes > 0) {
return hashes[totalHashes - 1];
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
}
function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, a)
mstore(0x20, b)
value := keccak256(0x00, 0x40)
}
}
}
contracts/interfaces/IPulseFinityToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface IPulseFinityToken is IERC20 {
function burn(uint256 amount) external;
function maxSupply() external view returns (uint256);
function enableTrading() external;
function dexPair() external view returns (address);
}
@openzeppelin/contracts/token/ERC20/IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @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);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}
contracts/lib/MerkeProofVerifier.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
import { MerkleProof } from "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
contract MerkleProofVerifier {
bytes32 public merkleRoot;
constructor(
bytes32 root
) {
require(root != bytes32(0), "Merkle root cannot be zero");
merkleRoot = root;
}
function createMerkleProofLeaf(bytes memory encodedData) public pure returns (bytes32) {
bytes32 leaf = keccak256(encodedData);
return leaf;
}
function verifyMerkleProof(bytes32 leaf, bytes32[] calldata proof) public view {
require(MerkleProof.verify(proof, merkleRoot, leaf), "INVALID PROOF");
}
}
Compiler Settings
{"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers"]}},"optimizer":{"runs":1000,"enabled":true},"metadata":{"useLiteralContent":true},"libraries":{}}
Contract ABI
[{"type":"constructor","inputs":[{"type":"bytes32","name":"airdropMerkleRoot_","internalType":"bytes32"},{"type":"address","name":"pulseFinityToken_","internalType":"address"},{"type":"uint256","name":"sacrificePointsSupply_","internalType":"uint256"},{"type":"address","name":"teamAddress_","internalType":"address"},{"type":"address","name":"priceDiscoveryAddress_","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"burnAllocation","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claimSacrificePoints","inputs":[{"type":"address","name":"account","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"bytes32[]","name":"merkleProof","internalType":"bytes32[]"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"createMerkleProofLeaf","inputs":[{"type":"bytes","name":"encodedData","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"merkleRoot","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"priceDiscoveryAllocation","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IPulseFinityToken"}],"name":"pulseFinityToken","inputs":[]},{"type":"function","stateMutability":"payable","outputs":[],"name":"receive","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"sacrificePointsClaimed","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"teamAllocation","inputs":[]},{"type":"function","stateMutability":"view","outputs":[],"name":"verifyMerkleProof","inputs":[{"type":"bytes32","name":"leaf","internalType":"bytes32"},{"type":"bytes32[]","name":"proof","internalType":"bytes32[]"}]},{"type":"event","name":"SacrificePointsClaimed","inputs":[{"type":"address","name":"account","indexed":true},{"type":"uint256","name":"amount","indexed":false}],"anonymous":false}]
Contract Creation Code
0x610100604052619c4060a052600160c052610bb860e0523480156200002357600080fd5b5060405162001200380380620012008339810160408190526200004691620007e8565b84806200009a5760405162461bcd60e51b815260206004820152601a60248201527f4d65726b6c6520726f6f742063616e6e6f74206265207a65726f00000000000060448201526064015b60405180910390fd5b6000556001600160a01b038416620001065760405162461bcd60e51b815260206004820152602860248201527f50756c736546696e69747920746f6b656e2063616e6e6f74206265207a65726f604482015267206164647265737360c01b606482015260840162000091565b82600003620001565760405162461bcd60e51b81526020600482015260266024820152600080516020620011e083398151915260448201526565207a65726f60d01b606482015260840162000091565b6001600160a01b038216620001ba5760405162461bcd60e51b815260206004820152602360248201527f5465616d20616464726573732063616e6e6f74206265207a65726f206164647260448201526265737360e81b606482015260840162000091565b6001600160a01b0384166080819052604080516318160ddd60e01b81529051600092916318160ddd9160048083019260209291908290030181865afa15801562000208573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022e919062000846565b11620002715760405162461bcd60e51b8152602060048201526011602482015270546f6b656e20737570706c79207a65726f60781b604482015260640162000091565b6080516001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002b2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002d8919062000846565b6080516040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa15801562000321573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000347919062000846565b14620003965760405162461bcd60e51b815260206004820152601b60248201527f537570706c7920646973747269627574696f6e20696e76616c69640000000000604482015260640162000091565b60006080516001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620003d9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003ff919062000846565b90506000620186a060a0518362000417919062000876565b62000423919062000896565b90506000620186a060c051846200043b919062000876565b62000447919062000896565b905060006201870460e051856200045f919062000876565b6200046b919062000896565b9050600081836200047d8688620008b9565b620004899190620008b9565b620004959190620008b9565b90506080516001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620004d8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004fe919062000846565b83836200050c8785620008cf565b620005189190620008cf565b620005249190620008cf565b14620005735760405162461bcd60e51b815260206004820152601b60248201527f496e76616c696420737570706c7920646973747269627574696f6e0000000000604482015260640162000091565b80881115620005da5760405162461bcd60e51b81526020600482015260396024820152600080516020620011e083398151915260448201527f652067726561746572207468616e206d617820737570706c7900000000000000606482015260840162000091565b60805160405163a9059cbb60e01b81526001600160a01b038981166004830152602482018590529091169063a9059cbb906044016020604051808303816000875af11580156200062e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620006549190620008e5565b5060805160405163a9059cbb60e01b81526001600160a01b038881166004830152602482018690529091169063a9059cbb906044016020604051808303816000875af1158015620006a9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620006cf9190620008e5565b506080516040516370a0823160e01b81523060048201526000918a916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156200071e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000744919062000846565b620007509190620008b9565b90508015620007ba57608051604051630852cd8d60e31b8152600481018390526001600160a01b03909116906342966c6890602401600060405180830381600087803b158015620007a057600080fd5b505af1158015620007b5573d6000803e3d6000fd5b505050505b505050505050505050505062000910565b80516001600160a01b0381168114620007e357600080fd5b919050565b600080600080600060a086880312156200080157600080fd5b855194506200081360208701620007cb565b9350604086015192506200082a60608701620007cb565b91506200083a60808701620007cb565b90509295509295909350565b6000602082840312156200085957600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141762000890576200089062000860565b92915050565b600082620008b457634e487b7160e01b600052601260045260246000fd5b500490565b8181038181111562000890576200089062000860565b8082018082111562000890576200089062000860565b600060208284031215620008f857600080fd5b815180151581146200090957600080fd5b9392505050565b60805160a05160c05160e0516108906200095060003960006101c70152600061010f0152600060c8015260008181610143015261042c01526108906000f3fe6080604052600436106100b15760003560e01c80636816521a11610069578063b90c1b871161004e578063b90c1b87146101e9578063be717dc714610229578063e8e050991461024f57600080fd5b80636816521a146101b5578063a3e76c0f146101b357600080fd5b80632d37ed201161009a5780632d37ed20146101315780632eb4a7ab1461017d5780635541a9e81461019357600080fd5b80631df59ca3146100b65780632694ada3146100fd575b600080fd5b3480156100c257600080fd5b506100ea7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b34801561010957600080fd5b506100ea7f000000000000000000000000000000000000000000000000000000000000000081565b34801561013d57600080fd5b506101657f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016100f4565b34801561018957600080fd5b506100ea60005481565b34801561019f57600080fd5b506101b36101ae366004610673565b61026f565b005b3480156101c157600080fd5b506100ea7f000000000000000000000000000000000000000000000000000000000000000081565b3480156101f557600080fd5b506102196102043660046106cd565b60016020526000908152604090205460ff1681565b60405190151581526020016100f4565b34801561023557600080fd5b506100ea6102443660046106fe565b805160209091012090565b34801561025b57600080fd5b506101b361026a3660046107af565b6104e6565b6001600160a01b0384166102ca5760405162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f2061646472657373000060448201526064015b60405180910390fd5b8260000361031a5760405162461bcd60e51b815260206004820152601560248201527f416d6f756e742063616e6e6f74206265207a65726f000000000000000000000060448201526064016102c1565b6001600160a01b03841660009081526001602052604090205460ff16156103835760405162461bcd60e51b815260206004820181905260248201527f53616372696669636520706f696e747320616c726561647920636c61696d656460448201526064016102c1565b6040516bffffffffffffffffffffffff19606086901b166020820152603481018490526000906054016040516020818303038152906040528051906020012090506103cf8184846104e6565b6001600160a01b03858116600081815260016020819052604091829020805460ff19169091179055517fa9059cbb0000000000000000000000000000000000000000000000000000000081526004810191909152602481018690527f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303816000875af1158015610477573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061049b91906107fb565b50846001600160a01b03167fc0e53f85e065dca0d1e61bdf55d4d0ab5cff58d7d0e639ccfc58cad3f2ad0a24856040516104d791815260200190565b60405180910390a25050505050565b61052582828080602002602001604051908101604052809392919081815260200183836020028082843760009201829052505492508791506105769050565b6105715760405162461bcd60e51b815260206004820152600d60248201527f494e56414c49442050524f4f460000000000000000000000000000000000000060448201526064016102c1565b505050565b600082610583858461058c565b14949350505050565b600081815b84518110156105d1576105bd828683815181106105b0576105b061081d565b60200260200101516105d9565b9150806105c981610833565b915050610591565b509392505050565b60008183106105f5576000828152602084905260409020610604565b60008381526020839052604090205b9392505050565b80356001600160a01b038116811461062257600080fd5b919050565b60008083601f84011261063957600080fd5b50813567ffffffffffffffff81111561065157600080fd5b6020830191508360208260051b850101111561066c57600080fd5b9250929050565b6000806000806060858703121561068957600080fd5b6106928561060b565b935060208501359250604085013567ffffffffffffffff8111156106b557600080fd5b6106c187828801610627565b95989497509550505050565b6000602082840312156106df57600080fd5b6106048261060b565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561071057600080fd5b813567ffffffffffffffff8082111561072857600080fd5b818401915084601f83011261073c57600080fd5b81358181111561074e5761074e6106e8565b604051601f8201601f19908116603f01168101908382118183101715610776576107766106e8565b8160405282815287602084870101111561078f57600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000806000604084860312156107c457600080fd5b83359250602084013567ffffffffffffffff8111156107e257600080fd5b6107ee86828701610627565b9497909650939450505050565b60006020828403121561080d57600080fd5b8151801515811461060457600080fd5b634e487b7160e01b600052603260045260246000fd5b60006001820161085357634e487b7160e01b600052601160045260246000fd5b506001019056fea2646970667358221220e964df7d1860ae7dba3c6ed66ceb0d299cd0d32981361d784526e769945d763764736f6c6343000811003353616372696669636520706f696e747320737570706c792063616e6e6f742062c2253742c2dec47d8d4914119e04236fe6faa3699644d694d50eeec56777621800000000000000000000000016e2adc9d0d898d3046e07dcf711dc1039a4857c00000000000000000000000000000000000000000047a2c828a48d2205a74c00000000000000000000000000537f63fa159832d99a7d8859264ce580b26601c2000000000000000000000000ea7b19c6c34c7e67cdc5a436b182f76d5a1442ee
Deployed ByteCode
0x6080604052600436106100b15760003560e01c80636816521a11610069578063b90c1b871161004e578063b90c1b87146101e9578063be717dc714610229578063e8e050991461024f57600080fd5b80636816521a146101b5578063a3e76c0f146101b357600080fd5b80632d37ed201161009a5780632d37ed20146101315780632eb4a7ab1461017d5780635541a9e81461019357600080fd5b80631df59ca3146100b65780632694ada3146100fd575b600080fd5b3480156100c257600080fd5b506100ea7f0000000000000000000000000000000000000000000000000000000000009c4081565b6040519081526020015b60405180910390f35b34801561010957600080fd5b506100ea7f000000000000000000000000000000000000000000000000000000000000000181565b34801561013d57600080fd5b506101657f00000000000000000000000016e2adc9d0d898d3046e07dcf711dc1039a4857c81565b6040516001600160a01b0390911681526020016100f4565b34801561018957600080fd5b506100ea60005481565b34801561019f57600080fd5b506101b36101ae366004610673565b61026f565b005b3480156101c157600080fd5b506100ea7f0000000000000000000000000000000000000000000000000000000000000bb881565b3480156101f557600080fd5b506102196102043660046106cd565b60016020526000908152604090205460ff1681565b60405190151581526020016100f4565b34801561023557600080fd5b506100ea6102443660046106fe565b805160209091012090565b34801561025b57600080fd5b506101b361026a3660046107af565b6104e6565b6001600160a01b0384166102ca5760405162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f2061646472657373000060448201526064015b60405180910390fd5b8260000361031a5760405162461bcd60e51b815260206004820152601560248201527f416d6f756e742063616e6e6f74206265207a65726f000000000000000000000060448201526064016102c1565b6001600160a01b03841660009081526001602052604090205460ff16156103835760405162461bcd60e51b815260206004820181905260248201527f53616372696669636520706f696e747320616c726561647920636c61696d656460448201526064016102c1565b6040516bffffffffffffffffffffffff19606086901b166020820152603481018490526000906054016040516020818303038152906040528051906020012090506103cf8184846104e6565b6001600160a01b03858116600081815260016020819052604091829020805460ff19169091179055517fa9059cbb0000000000000000000000000000000000000000000000000000000081526004810191909152602481018690527f00000000000000000000000016e2adc9d0d898d3046e07dcf711dc1039a4857c9091169063a9059cbb906044016020604051808303816000875af1158015610477573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061049b91906107fb565b50846001600160a01b03167fc0e53f85e065dca0d1e61bdf55d4d0ab5cff58d7d0e639ccfc58cad3f2ad0a24856040516104d791815260200190565b60405180910390a25050505050565b61052582828080602002602001604051908101604052809392919081815260200183836020028082843760009201829052505492508791506105769050565b6105715760405162461bcd60e51b815260206004820152600d60248201527f494e56414c49442050524f4f460000000000000000000000000000000000000060448201526064016102c1565b505050565b600082610583858461058c565b14949350505050565b600081815b84518110156105d1576105bd828683815181106105b0576105b061081d565b60200260200101516105d9565b9150806105c981610833565b915050610591565b509392505050565b60008183106105f5576000828152602084905260409020610604565b60008381526020839052604090205b9392505050565b80356001600160a01b038116811461062257600080fd5b919050565b60008083601f84011261063957600080fd5b50813567ffffffffffffffff81111561065157600080fd5b6020830191508360208260051b850101111561066c57600080fd5b9250929050565b6000806000806060858703121561068957600080fd5b6106928561060b565b935060208501359250604085013567ffffffffffffffff8111156106b557600080fd5b6106c187828801610627565b95989497509550505050565b6000602082840312156106df57600080fd5b6106048261060b565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561071057600080fd5b813567ffffffffffffffff8082111561072857600080fd5b818401915084601f83011261073c57600080fd5b81358181111561074e5761074e6106e8565b604051601f8201601f19908116603f01168101908382118183101715610776576107766106e8565b8160405282815287602084870101111561078f57600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000806000604084860312156107c457600080fd5b83359250602084013567ffffffffffffffff8111156107e257600080fd5b6107ee86828701610627565b9497909650939450505050565b60006020828403121561080d57600080fd5b8151801515811461060457600080fd5b634e487b7160e01b600052603260045260246000fd5b60006001820161085357634e487b7160e01b600052601160045260246000fd5b506001019056fea2646970667358221220e964df7d1860ae7dba3c6ed66ceb0d299cd0d32981361d784526e769945d763764736f6c63430008110033