Source Code
Overview
ETH Balance
0.003 ETH
Eth Value
$5.97 (@ $1,989.32/ETH)Latest 7 from a total of 7 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Send Blockhash | 19784954 | 694 days ago | IN | 0.003 ETH | 0.00022486 | ||||
| Send Blockhash | 19782929 | 694 days ago | IN | 0.003 ETH | 0.00161958 | ||||
| Send Blockhash | 17136171 | 1065 days ago | IN | 0.003 ETH | 0.00478582 | ||||
| Send Blockhash | 17130301 | 1066 days ago | IN | 0.003 ETH | 0.00476315 | ||||
| Send Blockhash | 16940298 | 1093 days ago | IN | 0.003 ETH | 0.0041799 | ||||
| Send Blockhash | 16889018 | 1100 days ago | IN | 0.003 ETH | 0.00196989 | ||||
| Send Blockhash | 16883345 | 1101 days ago | IN | 0.003 ETH | 0.0025042 |
Latest 6 internal transactions
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| Pay Native Gas F... | 19782929 | 694 days ago | 0.003 ETH | ||||
| Pay Native Gas F... | 17136171 | 1065 days ago | 0.003 ETH | ||||
| Pay Native Gas F... | 17130301 | 1066 days ago | 0.003 ETH | ||||
| Pay Native Gas F... | 16940298 | 1093 days ago | 0.003 ETH | ||||
| Pay Native Gas F... | 16889018 | 1100 days ago | 0.003 ETH | ||||
| Pay Native Gas F... | 16883345 | 1101 days ago | 0.003 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
EthereumStateSender
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2023-03-21
*/
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
/// @notice Library for converting numbers into strings and other string operations.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibString.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibString.sol)
library LibString {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CUSTOM ERRORS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The `length` of the output is too small to contain all the hex digits.
error HexLengthInsufficient();
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CONSTANTS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The constant returned when the `search` is not found in the string.
uint256 internal constant NOT_FOUND = type(uint256).max;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* DECIMAL OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns the base 10 decimal representation of `value`.
function toString(uint256 value) internal pure returns (string memory str) {
/// @solidity memory-safe-assembly
assembly {
// The maximum value of a uint256 contains 78 digits (1 byte per digit), but
// we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned.
// We will need 1 word for the trailing zeros padding, 1 word for the length,
// and 3 words for a maximum of 78 digits.
str := add(mload(0x40), 0x80)
// Update the free memory pointer to allocate.
mstore(0x40, add(str, 0x20))
// Zeroize the slot after the string.
mstore(str, 0)
// Cache the end of the memory to calculate the length later.
let end := str
let w := not(0) // Tsk.
// We write the string from rightmost digit to leftmost digit.
// The following is essentially a do-while loop that also handles the zero case.
for { let temp := value } 1 {} {
str := add(str, w) // `sub(str, 1)`.
// Write the character to the pointer.
// The ASCII index of the '0' character is 48.
mstore8(str, add(48, mod(temp, 10)))
// Keep dividing `temp` until zero.
temp := div(temp, 10)
if iszero(temp) { break }
}
let length := sub(end, str)
// Move the pointer 32 bytes leftwards to make room for the length.
str := sub(str, 0x20)
// Store the length.
mstore(str, length)
}
}
/// @dev Returns the base 10 decimal representation of `value`.
function toString(int256 value) internal pure returns (string memory str) {
if (value >= 0) {
return toString(uint256(value));
}
unchecked {
str = toString(uint256(-value));
}
/// @solidity memory-safe-assembly
assembly {
// We still have some spare memory space on the left,
// as we have allocated 3 words (96 bytes) for up to 78 digits.
let length := mload(str) // Load the string length.
mstore(str, 0x2d) // Store the '-' character.
str := sub(str, 1) // Move back the string pointer by a byte.
mstore(str, add(length, 1)) // Update the string length.
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* HEXADECIMAL OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns the hexadecimal representation of `value`,
/// left-padded to an input length of `length` bytes.
/// The output is prefixed with "0x" encoded using 2 hexadecimal digits per byte,
/// giving a total length of `length * 2 + 2` bytes.
/// Reverts if `length` is too small for the output to contain all the digits.
function toHexString(uint256 value, uint256 length) internal pure returns (string memory str) {
str = toHexStringNoPrefix(value, length);
/// @solidity memory-safe-assembly
assembly {
let strLength := add(mload(str), 2) // Compute the length.
mstore(str, 0x3078) // Write the "0x" prefix.
str := sub(str, 2) // Move the pointer.
mstore(str, strLength) // Write the length.
}
}
/// @dev Returns the hexadecimal representation of `value`,
/// left-padded to an input length of `length` bytes.
/// The output is prefixed with "0x" encoded using 2 hexadecimal digits per byte,
/// giving a total length of `length * 2` bytes.
/// Reverts if `length` is too small for the output to contain all the digits.
function toHexStringNoPrefix(uint256 value, uint256 length)
internal
pure
returns (string memory str)
{
/// @solidity memory-safe-assembly
assembly {
// We need 0x20 bytes for the trailing zeros padding, `length * 2` bytes
// for the digits, 0x02 bytes for the prefix, and 0x20 bytes for the length.
// We add 0x20 to the total and round down to a multiple of 0x20.
// (0x20 + 0x20 + 0x02 + 0x20) = 0x62.
str := add(mload(0x40), and(add(shl(1, length), 0x42), not(0x1f)))
// Allocate the memory.
mstore(0x40, add(str, 0x20))
// Zeroize the slot after the string.
mstore(str, 0)
// Cache the end to calculate the length later.
let end := str
// Store "0123456789abcdef" in scratch space.
mstore(0x0f, 0x30313233343536373839616263646566)
let start := sub(str, add(length, length))
let w := not(1) // Tsk.
let temp := value
// We write the string from rightmost digit to leftmost digit.
// The following is essentially a do-while loop that also handles the zero case.
for {} 1 {} {
str := add(str, w) // `sub(str, 2)`.
mstore8(add(str, 1), mload(and(temp, 15)))
mstore8(str, mload(and(shr(4, temp), 15)))
temp := shr(8, temp)
if iszero(xor(str, start)) { break }
}
if temp {
// Store the function selector of `HexLengthInsufficient()`.
mstore(0x00, 0x2194895a)
// Revert with (offset, size).
revert(0x1c, 0x04)
}
// Compute the string's length.
let strLength := sub(end, str)
// Move the pointer and write the length.
str := sub(str, 0x20)
mstore(str, strLength)
}
}
/// @dev Returns the hexadecimal representation of `value`.
/// The output is prefixed with "0x" and encoded using 2 hexadecimal digits per byte.
/// As address are 20 bytes long, the output will left-padded to have
/// a length of `20 * 2 + 2` bytes.
function toHexString(uint256 value) internal pure returns (string memory str) {
str = toHexStringNoPrefix(value);
/// @solidity memory-safe-assembly
assembly {
let strLength := add(mload(str), 2) // Compute the length.
mstore(str, 0x3078) // Write the "0x" prefix.
str := sub(str, 2) // Move the pointer.
mstore(str, strLength) // Write the length.
}
}
/// @dev Returns the hexadecimal representation of `value`.
/// The output is encoded using 2 hexadecimal digits per byte.
/// As address are 20 bytes long, the output will left-padded to have
/// a length of `20 * 2` bytes.
function toHexStringNoPrefix(uint256 value) internal pure returns (string memory str) {
/// @solidity memory-safe-assembly
assembly {
// We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length,
// 0x02 bytes for the prefix, and 0x40 bytes for the digits.
// The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x40) is 0xa0.
str := add(mload(0x40), 0x80)
// Allocate the memory.
mstore(0x40, add(str, 0x20))
// Zeroize the slot after the string.
mstore(str, 0)
// Cache the end to calculate the length later.
let end := str
// Store "0123456789abcdef" in scratch space.
mstore(0x0f, 0x30313233343536373839616263646566)
let w := not(1) // Tsk.
// We write the string from rightmost digit to leftmost digit.
// The following is essentially a do-while loop that also handles the zero case.
for { let temp := value } 1 {} {
str := add(str, w) // `sub(str, 2)`.
mstore8(add(str, 1), mload(and(temp, 15)))
mstore8(str, mload(and(shr(4, temp), 15)))
temp := shr(8, temp)
if iszero(temp) { break }
}
// Compute the string's length.
let strLength := sub(end, str)
// Move the pointer and write the length.
str := sub(str, 0x20)
mstore(str, strLength)
}
}
/// @dev Returns the hexadecimal representation of `value`.
/// The output is prefixed with "0x", encoded using 2 hexadecimal digits per byte,
/// and the alphabets are capitalized conditionally according to
/// https://eips.ethereum.org/EIPS/eip-55
function toHexStringChecksumed(address value) internal pure returns (string memory str) {
str = toHexString(value);
/// @solidity memory-safe-assembly
assembly {
let mask := shl(6, div(not(0), 255)) // `0b010000000100000000 ...`
let o := add(str, 0x22)
let hashed := and(keccak256(o, 40), mul(34, mask)) // `0b10001000 ... `
let t := shl(240, 136) // `0b10001000 << 240`
for { let i := 0 } 1 {} {
mstore(add(i, i), mul(t, byte(i, hashed)))
i := add(i, 1)
if eq(i, 20) { break }
}
mstore(o, xor(mload(o), shr(1, and(mload(0x00), and(mload(o), mask)))))
o := add(o, 0x20)
mstore(o, xor(mload(o), shr(1, and(mload(0x20), and(mload(o), mask)))))
}
}
/// @dev Returns the hexadecimal representation of `value`.
/// The output is prefixed with "0x" and encoded using 2 hexadecimal digits per byte.
function toHexString(address value) internal pure returns (string memory str) {
str = toHexStringNoPrefix(value);
/// @solidity memory-safe-assembly
assembly {
let strLength := add(mload(str), 2) // Compute the length.
mstore(str, 0x3078) // Write the "0x" prefix.
str := sub(str, 2) // Move the pointer.
mstore(str, strLength) // Write the length.
}
}
/// @dev Returns the hexadecimal representation of `value`.
/// The output is encoded using 2 hexadecimal digits per byte.
function toHexStringNoPrefix(address value) internal pure returns (string memory str) {
/// @solidity memory-safe-assembly
assembly {
str := mload(0x40)
// Allocate the memory.
// We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length,
// 0x02 bytes for the prefix, and 0x28 bytes for the digits.
// The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x28) is 0x80.
mstore(0x40, add(str, 0x80))
// Store "0123456789abcdef" in scratch space.
mstore(0x0f, 0x30313233343536373839616263646566)
str := add(str, 2)
mstore(str, 40)
let o := add(str, 0x20)
mstore(add(o, 40), 0)
value := shl(96, value)
// We write the string from rightmost digit to leftmost digit.
// The following is essentially a do-while loop that also handles the zero case.
for { let i := 0 } 1 {} {
let p := add(o, add(i, i))
let temp := byte(i, value)
mstore8(add(p, 1), mload(and(temp, 15)))
mstore8(p, mload(shr(4, temp)))
i := add(i, 1)
if eq(i, 20) { break }
}
}
}
/// @dev Returns the hex encoded string from the raw bytes.
/// The output is encoded using 2 hexadecimal digits per byte.
function toHexString(bytes memory raw) internal pure returns (string memory str) {
str = toHexStringNoPrefix(raw);
/// @solidity memory-safe-assembly
assembly {
let strLength := add(mload(str), 2) // Compute the length.
mstore(str, 0x3078) // Write the "0x" prefix.
str := sub(str, 2) // Move the pointer.
mstore(str, strLength) // Write the length.
}
}
/// @dev Returns the hex encoded string from the raw bytes.
/// The output is encoded using 2 hexadecimal digits per byte.
function toHexStringNoPrefix(bytes memory raw) internal pure returns (string memory str) {
/// @solidity memory-safe-assembly
assembly {
let length := mload(raw)
str := add(mload(0x40), 2) // Skip 2 bytes for the optional prefix.
mstore(str, add(length, length)) // Store the length of the output.
// Store "0123456789abcdef" in scratch space.
mstore(0x0f, 0x30313233343536373839616263646566)
let o := add(str, 0x20)
let end := add(raw, length)
for {} iszero(eq(raw, end)) {} {
raw := add(raw, 1)
mstore8(add(o, 1), mload(and(mload(raw), 15)))
mstore8(o, mload(and(shr(4, mload(raw)), 15)))
o := add(o, 2)
}
mstore(o, 0) // Zeroize the slot after the string.
mstore(0x40, and(add(o, 31), not(31))) // Allocate the memory.
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* RUNE STRING OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns the number of UTF characters in the string.
function runeCount(string memory s) internal pure returns (uint256 result) {
/// @solidity memory-safe-assembly
assembly {
if mload(s) {
mstore(0x00, div(not(0), 255))
mstore(0x20, 0x0202020202020202020202020202020202020202020202020303030304040506)
let o := add(s, 0x20)
let end := add(o, mload(s))
for { result := 1 } 1 { result := add(result, 1) } {
o := add(o, byte(0, mload(shr(250, mload(o)))))
if iszero(lt(o, end)) { break }
}
}
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* BYTE STRING OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
// For performance and bytecode compactness, all indices of the following operations
// are byte (ASCII) offsets, not UTF character offsets.
/// @dev Returns `subject` all occurrences of `search` replaced with `replacement`.
function replace(string memory subject, string memory search, string memory replacement)
internal
pure
returns (string memory result)
{
/// @solidity memory-safe-assembly
assembly {
let subjectLength := mload(subject)
let searchLength := mload(search)
let replacementLength := mload(replacement)
subject := add(subject, 0x20)
search := add(search, 0x20)
replacement := add(replacement, 0x20)
result := add(mload(0x40), 0x20)
let subjectEnd := add(subject, subjectLength)
if iszero(gt(searchLength, subjectLength)) {
let subjectSearchEnd := add(sub(subjectEnd, searchLength), 1)
let h := 0
if iszero(lt(searchLength, 32)) { h := keccak256(search, searchLength) }
let m := shl(3, sub(32, and(searchLength, 31)))
let s := mload(search)
for {} 1 {} {
let t := mload(subject)
// Whether the first `searchLength % 32` bytes of
// `subject` and `search` matches.
if iszero(shr(m, xor(t, s))) {
if h {
if iszero(eq(keccak256(subject, searchLength), h)) {
mstore(result, t)
result := add(result, 1)
subject := add(subject, 1)
if iszero(lt(subject, subjectSearchEnd)) { break }
continue
}
}
// Copy the `replacement` one word at a time.
for { let o := 0 } 1 {} {
mstore(add(result, o), mload(add(replacement, o)))
o := add(o, 0x20)
if iszero(lt(o, replacementLength)) { break }
}
result := add(result, replacementLength)
subject := add(subject, searchLength)
if searchLength {
if iszero(lt(subject, subjectSearchEnd)) { break }
continue
}
}
mstore(result, t)
result := add(result, 1)
subject := add(subject, 1)
if iszero(lt(subject, subjectSearchEnd)) { break }
}
}
let resultRemainder := result
result := add(mload(0x40), 0x20)
let k := add(sub(resultRemainder, result), sub(subjectEnd, subject))
// Copy the rest of the string one word at a time.
for {} lt(subject, subjectEnd) {} {
mstore(resultRemainder, mload(subject))
resultRemainder := add(resultRemainder, 0x20)
subject := add(subject, 0x20)
}
result := sub(result, 0x20)
// Zeroize the slot after the string.
let last := add(add(result, 0x20), k)
mstore(last, 0)
// Allocate memory for the length and the bytes,
// rounded up to a multiple of 32.
mstore(0x40, and(add(last, 31), not(31)))
// Store the length of the result.
mstore(result, k)
}
}
/// @dev Returns the byte index of the first location of `search` in `subject`,
/// searching from left to right, starting from `from`.
/// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.
function indexOf(string memory subject, string memory search, uint256 from)
internal
pure
returns (uint256 result)
{
/// @solidity memory-safe-assembly
assembly {
for { let subjectLength := mload(subject) } 1 {} {
if iszero(mload(search)) {
// `result = min(from, subjectLength)`.
result := xor(from, mul(xor(from, subjectLength), lt(subjectLength, from)))
break
}
let searchLength := mload(search)
let subjectStart := add(subject, 0x20)
result := not(0) // Initialize to `NOT_FOUND`.
subject := add(subjectStart, from)
let subjectSearchEnd := add(sub(add(subjectStart, subjectLength), searchLength), 1)
let m := shl(3, sub(32, and(searchLength, 31)))
let s := mload(add(search, 0x20))
if iszero(lt(subject, subjectSearchEnd)) { break }
if iszero(lt(searchLength, 32)) {
for { let h := keccak256(add(search, 0x20), searchLength) } 1 {} {
if iszero(shr(m, xor(mload(subject), s))) {
if eq(keccak256(subject, searchLength), h) {
result := sub(subject, subjectStart)
break
}
}
subject := add(subject, 1)
if iszero(lt(subject, subjectSearchEnd)) { break }
}
break
}
for {} 1 {} {
if iszero(shr(m, xor(mload(subject), s))) {
result := sub(subject, subjectStart)
break
}
subject := add(subject, 1)
if iszero(lt(subject, subjectSearchEnd)) { break }
}
break
}
}
}
/// @dev Returns the byte index of the first location of `search` in `subject`,
/// searching from left to right.
/// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.
function indexOf(string memory subject, string memory search)
internal
pure
returns (uint256 result)
{
result = indexOf(subject, search, 0);
}
/// @dev Returns the byte index of the first location of `search` in `subject`,
/// searching from right to left, starting from `from`.
/// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.
function lastIndexOf(string memory subject, string memory search, uint256 from)
internal
pure
returns (uint256 result)
{
/// @solidity memory-safe-assembly
assembly {
for {} 1 {} {
let searchLength := mload(search)
let fromMax := sub(mload(subject), searchLength)
if iszero(gt(fromMax, from)) { from := fromMax }
if iszero(mload(search)) {
result := from
break
}
result := not(0) // Initialize to `NOT_FOUND`.
let subjectSearchEnd := sub(add(subject, 0x20), 1)
subject := add(add(subject, 0x20), from)
if iszero(gt(subject, subjectSearchEnd)) { break }
// As this function is not too often used,
// we shall simply use keccak256 for smaller bytecode size.
for { let h := keccak256(add(search, 0x20), searchLength) } 1 {} {
if eq(keccak256(subject, searchLength), h) {
result := sub(subject, add(subjectSearchEnd, 1))
break
}
subject := sub(subject, 1)
if iszero(gt(subject, subjectSearchEnd)) { break }
}
break
}
}
}
/// @dev Returns the byte index of the first location of `search` in `subject`,
/// searching from right to left.
/// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.
function lastIndexOf(string memory subject, string memory search)
internal
pure
returns (uint256 result)
{
result = lastIndexOf(subject, search, uint256(int256(-1)));
}
/// @dev Returns whether `subject` starts with `search`.
function startsWith(string memory subject, string memory search)
internal
pure
returns (bool result)
{
/// @solidity memory-safe-assembly
assembly {
let searchLength := mload(search)
// Just using keccak256 directly is actually cheaper.
// forgefmt: disable-next-item
result := and(
iszero(gt(searchLength, mload(subject))),
eq(
keccak256(add(subject, 0x20), searchLength),
keccak256(add(search, 0x20), searchLength)
)
)
}
}
/// @dev Returns whether `subject` ends with `search`.
function endsWith(string memory subject, string memory search)
internal
pure
returns (bool result)
{
/// @solidity memory-safe-assembly
assembly {
let searchLength := mload(search)
let subjectLength := mload(subject)
// Whether `search` is not longer than `subject`.
let withinRange := iszero(gt(searchLength, subjectLength))
// Just using keccak256 directly is actually cheaper.
// forgefmt: disable-next-item
result := and(
withinRange,
eq(
keccak256(
// `subject + 0x20 + max(subjectLength - searchLength, 0)`.
add(add(subject, 0x20), mul(withinRange, sub(subjectLength, searchLength))),
searchLength
),
keccak256(add(search, 0x20), searchLength)
)
)
}
}
/// @dev Returns `subject` repeated `times`.
function repeat(string memory subject, uint256 times)
internal
pure
returns (string memory result)
{
/// @solidity memory-safe-assembly
assembly {
let subjectLength := mload(subject)
if iszero(or(iszero(times), iszero(subjectLength))) {
subject := add(subject, 0x20)
result := mload(0x40)
let output := add(result, 0x20)
for {} 1 {} {
// Copy the `subject` one word at a time.
for { let o := 0 } 1 {} {
mstore(add(output, o), mload(add(subject, o)))
o := add(o, 0x20)
if iszero(lt(o, subjectLength)) { break }
}
output := add(output, subjectLength)
times := sub(times, 1)
if iszero(times) { break }
}
// Zeroize the slot after the string.
mstore(output, 0)
// Store the length.
let resultLength := sub(output, add(result, 0x20))
mstore(result, resultLength)
// Allocate memory for the length and the bytes,
// rounded up to a multiple of 32.
mstore(0x40, add(result, and(add(resultLength, 63), not(31))))
}
}
}
/// @dev Returns a copy of `subject` sliced from `start` to `end` (exclusive).
/// `start` and `end` are byte offsets.
function slice(string memory subject, uint256 start, uint256 end)
internal
pure
returns (string memory result)
{
/// @solidity memory-safe-assembly
assembly {
let subjectLength := mload(subject)
if iszero(gt(subjectLength, end)) { end := subjectLength }
if iszero(gt(subjectLength, start)) { start := subjectLength }
if lt(start, end) {
result := mload(0x40)
let resultLength := sub(end, start)
mstore(result, resultLength)
subject := add(subject, start)
let w := not(31)
// Copy the `subject` one word at a time, backwards.
for { let o := and(add(resultLength, 31), w) } 1 {} {
mstore(add(result, o), mload(add(subject, o)))
o := add(o, w) // `sub(o, 0x20)`.
if iszero(o) { break }
}
// Zeroize the slot after the string.
mstore(add(add(result, 0x20), resultLength), 0)
// Allocate memory for the length and the bytes,
// rounded up to a multiple of 32.
mstore(0x40, add(result, and(add(resultLength, 63), w)))
}
}
}
/// @dev Returns a copy of `subject` sliced from `start` to the end of the string.
/// `start` is a byte offset.
function slice(string memory subject, uint256 start)
internal
pure
returns (string memory result)
{
result = slice(subject, start, uint256(int256(-1)));
}
/// @dev Returns all the indices of `search` in `subject`.
/// The indices are byte offsets.
function indicesOf(string memory subject, string memory search)
internal
pure
returns (uint256[] memory result)
{
/// @solidity memory-safe-assembly
assembly {
let subjectLength := mload(subject)
let searchLength := mload(search)
if iszero(gt(searchLength, subjectLength)) {
subject := add(subject, 0x20)
search := add(search, 0x20)
result := add(mload(0x40), 0x20)
let subjectStart := subject
let subjectSearchEnd := add(sub(add(subject, subjectLength), searchLength), 1)
let h := 0
if iszero(lt(searchLength, 32)) { h := keccak256(search, searchLength) }
let m := shl(3, sub(32, and(searchLength, 31)))
let s := mload(search)
for {} 1 {} {
let t := mload(subject)
// Whether the first `searchLength % 32` bytes of
// `subject` and `search` matches.
if iszero(shr(m, xor(t, s))) {
if h {
if iszero(eq(keccak256(subject, searchLength), h)) {
subject := add(subject, 1)
if iszero(lt(subject, subjectSearchEnd)) { break }
continue
}
}
// Append to `result`.
mstore(result, sub(subject, subjectStart))
result := add(result, 0x20)
// Advance `subject` by `searchLength`.
subject := add(subject, searchLength)
if searchLength {
if iszero(lt(subject, subjectSearchEnd)) { break }
continue
}
}
subject := add(subject, 1)
if iszero(lt(subject, subjectSearchEnd)) { break }
}
let resultEnd := result
// Assign `result` to the free memory pointer.
result := mload(0x40)
// Store the length of `result`.
mstore(result, shr(5, sub(resultEnd, add(result, 0x20))))
// Allocate memory for result.
// We allocate one more word, so this array can be recycled for {split}.
mstore(0x40, add(resultEnd, 0x20))
}
}
}
/// @dev Returns a arrays of strings based on the `delimiter` inside of the `subject` string.
function split(string memory subject, string memory delimiter)
internal
pure
returns (string[] memory result)
{
uint256[] memory indices = indicesOf(subject, delimiter);
/// @solidity memory-safe-assembly
assembly {
let w := not(31)
let indexPtr := add(indices, 0x20)
let indicesEnd := add(indexPtr, shl(5, add(mload(indices), 1)))
mstore(add(indicesEnd, w), mload(subject))
mstore(indices, add(mload(indices), 1))
let prevIndex := 0
for {} 1 {} {
let index := mload(indexPtr)
mstore(indexPtr, 0x60)
if iszero(eq(index, prevIndex)) {
let element := mload(0x40)
let elementLength := sub(index, prevIndex)
mstore(element, elementLength)
// Copy the `subject` one word at a time, backwards.
for { let o := and(add(elementLength, 31), w) } 1 {} {
mstore(add(element, o), mload(add(add(subject, prevIndex), o)))
o := add(o, w) // `sub(o, 0x20)`.
if iszero(o) { break }
}
// Zeroize the slot after the string.
mstore(add(add(element, 0x20), elementLength), 0)
// Allocate memory for the length and the bytes,
// rounded up to a multiple of 32.
mstore(0x40, add(element, and(add(elementLength, 63), w)))
// Store the `element` into the array.
mstore(indexPtr, element)
}
prevIndex := add(index, mload(delimiter))
indexPtr := add(indexPtr, 0x20)
if iszero(lt(indexPtr, indicesEnd)) { break }
}
result := indices
if iszero(mload(delimiter)) {
result := add(indices, 0x20)
mstore(result, sub(mload(indices), 2))
}
}
}
/// @dev Returns a concatenated string of `a` and `b`.
/// Cheaper than `string.concat()` and does not de-align the free memory pointer.
function concat(string memory a, string memory b)
internal
pure
returns (string memory result)
{
/// @solidity memory-safe-assembly
assembly {
let w := not(31)
result := mload(0x40)
let aLength := mload(a)
// Copy `a` one word at a time, backwards.
for { let o := and(add(mload(a), 32), w) } 1 {} {
mstore(add(result, o), mload(add(a, o)))
o := add(o, w) // `sub(o, 0x20)`.
if iszero(o) { break }
}
let bLength := mload(b)
let output := add(result, mload(a))
// Copy `b` one word at a time, backwards.
for { let o := and(add(bLength, 32), w) } 1 {} {
mstore(add(output, o), mload(add(b, o)))
o := add(o, w) // `sub(o, 0x20)`.
if iszero(o) { break }
}
let totalLength := add(aLength, bLength)
let last := add(add(result, 0x20), totalLength)
// Zeroize the slot after the string.
mstore(last, 0)
// Stores the length.
mstore(result, totalLength)
// Allocate memory for the length and the bytes,
// rounded up to a multiple of 32.
mstore(0x40, and(add(last, 31), w))
}
}
/// @dev Returns a copy of the string in either lowercase or UPPERCASE.
function toCase(string memory subject, bool toUpper)
internal
pure
returns (string memory result)
{
/// @solidity memory-safe-assembly
assembly {
let length := mload(subject)
if length {
result := add(mload(0x40), 0x20)
subject := add(subject, 1)
let flags := shl(add(70, shl(5, toUpper)), 67108863)
let w := not(0)
for { let o := length } 1 {} {
o := add(o, w)
let b := and(0xff, mload(add(subject, o)))
mstore8(add(result, o), xor(b, and(shr(b, flags), 0x20)))
if iszero(o) { break }
}
// Restore the result.
result := mload(0x40)
// Stores the string length.
mstore(result, length)
// Zeroize the slot after the string.
let last := add(add(result, 0x20), length)
mstore(last, 0)
// Allocate memory for the length and the bytes,
// rounded up to a multiple of 32.
mstore(0x40, and(add(last, 31), not(31)))
}
}
}
/// @dev Returns a lowercased copy of the string.
function lower(string memory subject) internal pure returns (string memory result) {
result = toCase(subject, false);
}
/// @dev Returns an UPPERCASED copy of the string.
function upper(string memory subject) internal pure returns (string memory result) {
result = toCase(subject, true);
}
/// @dev Escapes the string to be used within HTML tags.
function escapeHTML(string memory s) internal pure returns (string memory result) {
/// @solidity memory-safe-assembly
assembly {
for {
let end := add(s, mload(s))
result := add(mload(0x40), 0x20)
// Store the bytes of the packed offsets and strides into the scratch space.
// `packed = (stride << 5) | offset`. Max offset is 20. Max stride is 6.
mstore(0x1f, 0x900094)
mstore(0x08, 0xc0000000a6ab)
// Store ""&'<>" into the scratch space.
mstore(0x00, shl(64, 0x2671756f743b26616d703b262333393b266c743b2667743b))
} iszero(eq(s, end)) {} {
s := add(s, 1)
let c := and(mload(s), 0xff)
// Not in `["\"","'","&","<",">"]`.
if iszero(and(shl(c, 1), 0x500000c400000000)) {
mstore8(result, c)
result := add(result, 1)
continue
}
let t := shr(248, mload(c))
mstore(result, mload(and(t, 31)))
result := add(result, shr(5, t))
}
let last := result
// Zeroize the slot after the string.
mstore(last, 0)
// Restore the result to the start of the free memory.
result := mload(0x40)
// Store the length of the result.
mstore(result, sub(last, add(result, 0x20)))
// Allocate memory for the length and the bytes,
// rounded up to a multiple of 32.
mstore(0x40, and(add(last, 31), not(31)))
}
}
/// @dev Escapes the string to be used within double-quotes in a JSON.
function escapeJSON(string memory s) internal pure returns (string memory result) {
/// @solidity memory-safe-assembly
assembly {
for {
let end := add(s, mload(s))
result := add(mload(0x40), 0x20)
// Store "\\u0000" in scratch space.
// Store "0123456789abcdef" in scratch space.
// Also, store `{0x08:"b", 0x09:"t", 0x0a:"n", 0x0c:"f", 0x0d:"r"}`.
// into the scratch space.
mstore(0x15, 0x5c75303030303031323334353637383961626364656662746e006672)
// Bitmask for detecting `["\"","\\"]`.
let e := or(shl(0x22, 1), shl(0x5c, 1))
} iszero(eq(s, end)) {} {
s := add(s, 1)
let c := and(mload(s), 0xff)
if iszero(lt(c, 0x20)) {
if iszero(and(shl(c, 1), e)) {
// Not in `["\"","\\"]`.
mstore8(result, c)
result := add(result, 1)
continue
}
mstore8(result, 0x5c) // "\\".
mstore8(add(result, 1), c)
result := add(result, 2)
continue
}
if iszero(and(shl(c, 1), 0x3700)) {
// Not in `["\b","\t","\n","\f","\d"]`.
mstore8(0x1d, mload(shr(4, c))) // Hex value.
mstore8(0x1e, mload(and(c, 15))) // Hex value.
mstore(result, mload(0x19)) // "\\u00XX".
result := add(result, 6)
continue
}
mstore8(result, 0x5c) // "\\".
mstore8(add(result, 1), mload(add(c, 8)))
result := add(result, 2)
}
let last := result
// Zeroize the slot after the string.
mstore(last, 0)
// Restore the result to the start of the free memory.
result := mload(0x40)
// Store the length of the result.
mstore(result, sub(last, add(result, 0x20)))
// Allocate memory for the length and the bytes,
// rounded up to a multiple of 32.
mstore(0x40, and(add(last, 31), not(31)))
}
}
/// @dev Returns whether `a` equals `b`.
function eq(string memory a, string memory b) internal pure returns (bool result) {
assembly {
result := eq(keccak256(add(a, 0x20), mload(a)), keccak256(add(b, 0x20), mload(b)))
}
}
/// @dev Packs a single string with its length into a single word.
/// Returns `bytes32(0)` if the length is zero or greater than 31.
function packOne(string memory a) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
// We don't need to zero right pad the string,
// since this is our own custom non-standard packing scheme.
result :=
mul(
// Load the length and the bytes.
mload(add(a, 0x1f)),
// `length != 0 && length < 32`. Abuses underflow.
// Assumes that the length is valid and within the block gas limit.
lt(sub(mload(a), 1), 0x1f)
)
}
}
/// @dev Unpacks a string packed using {packOne}.
/// Returns the empty string if `packed` is `bytes32(0)`.
/// If `packed` is not an output of {packOne}, the output behaviour is undefined.
function unpackOne(bytes32 packed) internal pure returns (string memory result) {
/// @solidity memory-safe-assembly
assembly {
// Grab the free memory pointer.
result := mload(0x40)
// Allocate 2 words (1 for the length, 1 for the bytes).
mstore(0x40, add(result, 0x40))
// Zeroize the length slot.
mstore(result, 0)
// Store the length and bytes.
mstore(add(result, 0x1f), packed)
// Right pad with zeroes.
mstore(add(add(result, 0x20), mload(result)), 0)
}
}
/// @dev Packs two strings with their lengths into a single word.
/// Returns `bytes32(0)` if combined length is zero or greater than 30.
function packTwo(string memory a, string memory b) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let aLength := mload(a)
// We don't need to zero right pad the strings,
// since this is our own custom non-standard packing scheme.
result :=
mul(
// Load the length and the bytes of `a` and `b`.
or(
shl(shl(3, sub(0x1f, aLength)), mload(add(a, aLength))),
mload(sub(add(b, 0x1e), aLength))
),
// `totalLength != 0 && totalLength < 31`. Abuses underflow.
// Assumes that the lengths are valid and within the block gas limit.
lt(sub(add(aLength, mload(b)), 1), 0x1e)
)
}
}
/// @dev Unpacks strings packed using {packTwo}.
/// Returns the empty strings if `packed` is `bytes32(0)`.
/// If `packed` is not an output of {packTwo}, the output behaviour is undefined.
function unpackTwo(bytes32 packed)
internal
pure
returns (string memory resultA, string memory resultB)
{
/// @solidity memory-safe-assembly
assembly {
// Grab the free memory pointer.
resultA := mload(0x40)
resultB := add(resultA, 0x40)
// Allocate 2 words for each string (1 for the length, 1 for the byte). Total 4 words.
mstore(0x40, add(resultB, 0x40))
// Zeroize the length slots.
mstore(resultA, 0)
mstore(resultB, 0)
// Store the lengths and bytes.
mstore(add(resultA, 0x1f), packed)
mstore(add(resultB, 0x1f), mload(add(add(resultA, 0x20), mload(resultA))))
// Right pad with zeroes.
mstore(add(add(resultA, 0x20), mload(resultA)), 0)
mstore(add(add(resultB, 0x20), mload(resultB)), 0)
}
}
/// @dev Directly returns `a` without copying.
function directReturn(string memory a) internal pure {
assembly {
// Assumes that the string does not start from the scratch space.
let retStart := sub(a, 0x20)
let retSize := add(mload(a), 0x40)
// Right pad with zeroes. Just in case the string is produced
// by a method that doesn't zero right pad.
mstore(add(retStart, retSize), 0)
// Store the return offset.
mstore(retStart, 0x20)
// End the transaction, returning the string.
return(retStart, retSize)
}
}
}
interface IAxelarGateway {
/**
* \
* |* Errors *|
* \*********
*/
error NotSelf();
error NotProxy();
error InvalidCodeHash();
error SetupFailed();
error InvalidAuthModule();
error InvalidTokenDeployer();
error InvalidAmount();
error InvalidChainId();
error InvalidCommands();
error TokenDoesNotExist(string symbol);
error TokenAlreadyExists(string symbol);
error TokenDeployFailed(string symbol);
error TokenContractDoesNotExist(address token);
error BurnFailed(string symbol);
error MintFailed(string symbol);
error InvalidSetMintLimitsParams();
error ExceedMintLimit(string symbol);
/**
* \
* |* Events *|
* \*********
*/
event TokenSent(
address indexed sender, string destinationChain, string destinationAddress, string symbol, uint256 amount
);
event ContractCall(
address indexed sender,
string destinationChain,
string destinationContractAddress,
bytes32 indexed payloadHash,
bytes payload
);
event ContractCallWithToken(
address indexed sender,
string destinationChain,
string destinationContractAddress,
bytes32 indexed payloadHash,
bytes payload,
string symbol,
uint256 amount
);
event Executed(bytes32 indexed commandId);
event TokenDeployed(string symbol, address tokenAddresses);
event ContractCallApproved(
bytes32 indexed commandId,
string sourceChain,
string sourceAddress,
address indexed contractAddress,
bytes32 indexed payloadHash,
bytes32 sourceTxHash,
uint256 sourceEventIndex
);
event ContractCallApprovedWithMint(
bytes32 indexed commandId,
string sourceChain,
string sourceAddress,
address indexed contractAddress,
bytes32 indexed payloadHash,
string symbol,
uint256 amount,
bytes32 sourceTxHash,
uint256 sourceEventIndex
);
event TokenMintLimitUpdated(string symbol, uint256 limit);
event OperatorshipTransferred(bytes newOperatorsData);
event Upgraded(address indexed implementation);
/**
* \
* |* Public Functions *|
* \*******************
*/
function sendToken(
string calldata destinationChain,
string calldata destinationAddress,
string calldata symbol,
uint256 amount
) external;
function callContract(string calldata destinationChain, string calldata contractAddress, bytes calldata payload)
external;
function callContractWithToken(
string calldata destinationChain,
string calldata contractAddress,
bytes calldata payload,
string calldata symbol,
uint256 amount
) external;
function isContractCallApproved(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
address contractAddress,
bytes32 payloadHash
) external view returns (bool);
function isContractCallAndMintApproved(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
address contractAddress,
bytes32 payloadHash,
string calldata symbol,
uint256 amount
) external view returns (bool);
function validateContractCall(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes32 payloadHash
) external returns (bool);
function validateContractCallAndMint(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes32 payloadHash,
string calldata symbol,
uint256 amount
) external returns (bool);
/**
* \
* |* Getters *|
* \**********
*/
function authModule() external view returns (address);
function tokenDeployer() external view returns (address);
function tokenMintLimit(string memory symbol) external view returns (uint256);
function tokenMintAmount(string memory symbol) external view returns (uint256);
function allTokensFrozen() external view returns (bool);
function implementation() external view returns (address);
function tokenAddresses(string memory symbol) external view returns (address);
function tokenFrozen(string memory symbol) external view returns (bool);
function isCommandExecuted(bytes32 commandId) external view returns (bool);
function adminEpoch() external view returns (uint256);
function adminThreshold(uint256 epoch) external view returns (uint256);
function admins(uint256 epoch) external view returns (address[] memory);
/**
* \
* |* Admin Functions *|
* \******************
*/
function setTokenMintLimits(string[] calldata symbols, uint256[] calldata limits) external;
function upgrade(address newImplementation, bytes32 newImplementationCodeHash, bytes calldata setupParams)
external;
/**
* \
* |* External Functions *|
* \*********************
*/
function setup(bytes calldata params) external;
function execute(bytes calldata input) external;
}
interface IAxelarGasReceiverProxy {
function payNativeGasForContractCall(
address sender,
string memory destinationChain,
string memory destinationAddress,
bytes memory payload,
address refundAddress
) external payable;
}
contract EthereumStateSender {
using LibString for address;
error ONLY_ADMIN();
error VALUE_TOO_LOW();
address public admin;
address public constant AXELAR_GATEWAY = 0x4F4495243837681061C4743b74B3eEdf548D56A5;
address public constant AXELAR_GAS_RECEIVER = 0x2d5d7d31F671F86C782533cc367F14109a082712;
uint256 public sendBlockHashMinValue = 3000000000000000; // 0.003 ETH
uint256 public setRecipientMinValue = 1000000000000000; // 0.001 ETH
mapping(uint256 => uint256) public blockNumbers;
mapping(uint256 => bytes32) public blockHashes;
mapping(uint256 => mapping(string => uint256)) public destinationChains;
/// @notice Emitted when a recipient is set
/// @param _sender The sender of the transaction
/// @param _recipient The recipient of the transaction
/// @param _destinationChain The destination chain
event RecipientSet(address indexed _sender, address indexed _recipient, string _destinationChain);
/// @notice Emitted when a blockhash is sent
/// @param _blockNumber The block number
/// @param _blockHash The block hash
/// @param _destinationChain The destination chain
event BlockhashSent(uint256 indexed _blockNumber, bytes32 _blockHash, string _destinationChain);
/// @notice Emitted when a new admin is set
/// @param _admin The admin address
event AdminSet(address _admin);
/// @notice Emitted when a new sendBlockhashMinValue is set
/// @param _minValue The min eth value to pass on the call
event SendBlockhashMinValueSet(uint256 _minValue);
/// @notice Emitted when a new setRecipientMinValue is set
/// @param _minValue The min eth value to pass on the call
event SetRecipientMinValueSet(uint256 _minValue);
constructor(address _admin) {
admin = _admin;
}
/// @notice Send a blockhash to a destination chain (it will use the previous block's blockhash)
/// @param _destinationChain The destination chain
/// @param _destinationContract The destination contract
function sendBlockhash(string calldata _destinationChain, address _destinationContract) public payable {
if (msg.value < sendBlockHashMinValue) revert VALUE_TOO_LOW();
uint256 currentPeriod = getCurrentPeriod();
// Only one submission per period
if (blockNumbers[currentPeriod] == 0 && currentPeriod + 5 minutes < block.timestamp) {
blockHashes[currentPeriod] = blockhash(block.number - 1);
blockNumbers[currentPeriod] = block.number - 1;
}
if (blockNumbers[currentPeriod] != 0 && destinationChains[currentPeriod][_destinationChain] == 0) {
_sendBlockhash(_destinationContract, _destinationChain, currentPeriod);
}
}
/// @notice Send a blockhash to a list of destination chains (it will use the previous block's blockhash)
/// @param _destinationChains The destination chains array
/// @param _destinationContracts The destination contracts array
function sendBlockhash(string[] calldata _destinationChains, address[] calldata _destinationContracts) external payable {
uint256 lenght = _destinationChains.length;
if (msg.value < sendBlockHashMinValue * lenght) revert VALUE_TOO_LOW();
for (uint256 i; i < lenght;) {
sendBlockhash(_destinationChains[i], _destinationContracts[i]);
unchecked {
++i;
}
}
}
/// @notice Send a blockhash to a destination chain, function used only in emergency cases
/// @param _destinationChain The destination chain
/// @param _destinationContract The destination contract
function sendBlockhashEmergency(string calldata _destinationChain, address _destinationContract) external payable {
if (msg.sender != admin) revert ONLY_ADMIN();
if (msg.value < sendBlockHashMinValue) revert VALUE_TOO_LOW();
uint256 currentPeriod = getCurrentPeriod();
_sendBlockhash(_destinationContract, _destinationChain, currentPeriod);
}
/// @notice Internal function to send a blockhash to a destination chain
/// @param destinationChain The destination chain
/// @param destinationContract The destination contract
/// @param currentPeriod Current period
function _sendBlockhash(address destinationContract, string calldata destinationChain, uint256 currentPeriod) internal {
string memory _destinationContract = destinationContract.toHexStringChecksumed();
bytes memory payload =
abi.encodeWithSignature("setEthBlockHash(uint256,bytes32)", blockNumbers[currentPeriod], blockHashes[currentPeriod]);
// pay gas in eth
// the gas in exceed will be reimbursed to the msg.sender
IAxelarGasReceiverProxy(AXELAR_GAS_RECEIVER).payNativeGasForContractCall{value: msg.value}(
address(this), destinationChain, _destinationContract, payload, msg.sender
);
IAxelarGateway(AXELAR_GATEWAY).callContract(destinationChain, _destinationContract, payload);
destinationChains[currentPeriod][destinationChain] += 1;
emit BlockhashSent(blockNumbers[currentPeriod], blockHashes[currentPeriod], destinationChain);
}
/// @notice Set a recipient for a destination chain
/// @param destinationChain The destination chain
/// @param destinationContract The destination contract
/// @param recipient The recipient
function setRecipient(string calldata destinationChain, address destinationContract, address recipient) external payable {
if (msg.value < setRecipientMinValue) revert VALUE_TOO_LOW();
string memory _destinationContract = destinationContract.toHexStringChecksumed();
bytes memory payload =
abi.encodeWithSignature("setRecipient(address,address)", msg.sender, recipient);
IAxelarGasReceiverProxy(AXELAR_GAS_RECEIVER).payNativeGasForContractCall{value: msg.value}(
address(this), destinationChain, _destinationContract, payload, msg.sender
);
IAxelarGateway(AXELAR_GATEWAY).callContract(
destinationChain, _destinationContract, payload
);
emit RecipientSet(msg.sender, recipient, destinationChain);
}
/// @notice Set min value (ETH) to send during the sendBlockhash() call
/// @param minValue min value to set
function setSendBlockHashMinValue(uint256 minValue) external {
if (msg.sender != admin) revert ONLY_ADMIN();
sendBlockHashMinValue = minValue;
emit SendBlockhashMinValueSet(minValue);
}
/// @notice Set min value (ETH) to send during the setRecipient() call
/// @param minValue min value to set
function setSetRecipientMinValue(uint256 minValue) external {
if (msg.sender != admin) revert ONLY_ADMIN();
setRecipientMinValue = minValue;
emit SetRecipientMinValueSet(minValue);
}
/// @notice Set a new admin
/// @param _admin admin address
function setAdmin(address _admin) external {
if (msg.sender != admin) revert ONLY_ADMIN();
admin = _admin;
emit AdminSet(_admin);
}
/// @notice Generate proof parameters for a given user, gauge and time
/// @param _user The user
/// @param _gauge The gauge
/// @param _time The time
function generateEthProofParams(address _user, address _gauge, uint256 _time)
external
view
returns (address, address, uint256, uint256[6] memory _positions, uint256)
{
uint256 lastUserVotePosition = uint256(keccak256(abi.encode(keccak256(abi.encode(11, _user)), _gauge)));
_positions[0] = lastUserVotePosition;
uint256 pointWeightsPosition =
uint256(keccak256(abi.encode(keccak256(abi.encode(keccak256(abi.encode(12, _gauge)), _time)))));
uint256 i;
for (i = 0; i < 2; i++) {
_positions[1 + i] = pointWeightsPosition + i;
}
uint256 voteUserSlopePosition =
uint256(keccak256(abi.encode(keccak256(abi.encode(keccak256(abi.encode(9, _user)), _gauge)))));
for (i = 0; i < 3; i++) {
_positions[3 + i] = voteUserSlopePosition + i;
}
return (_user, _gauge, _time, _positions, block.number);
}
/// @notice Get current period (last thursday at midnight utc time)
function getCurrentPeriod() public view returns (uint256) {
return (block.timestamp / 1 weeks * 1 weeks);
}
receive() external payable {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ONLY_ADMIN","type":"error"},{"inputs":[],"name":"VALUE_TOO_LOW","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_admin","type":"address"}],"name":"AdminSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_blockNumber","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_blockHash","type":"bytes32"},{"indexed":false,"internalType":"string","name":"_destinationChain","type":"string"}],"name":"BlockhashSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_sender","type":"address"},{"indexed":true,"internalType":"address","name":"_recipient","type":"address"},{"indexed":false,"internalType":"string","name":"_destinationChain","type":"string"}],"name":"RecipientSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_minValue","type":"uint256"}],"name":"SendBlockhashMinValueSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_minValue","type":"uint256"}],"name":"SetRecipientMinValueSet","type":"event"},{"inputs":[],"name":"AXELAR_GAS_RECEIVER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"AXELAR_GATEWAY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"blockHashes","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"blockNumbers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"string","name":"","type":"string"}],"name":"destinationChains","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_gauge","type":"address"},{"internalType":"uint256","name":"_time","type":"uint256"}],"name":"generateEthProofParams","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256[6]","name":"_positions","type":"uint256[6]"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sendBlockHashMinValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_destinationChain","type":"string"},{"internalType":"address","name":"_destinationContract","type":"address"}],"name":"sendBlockhash","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string[]","name":"_destinationChains","type":"string[]"},{"internalType":"address[]","name":"_destinationContracts","type":"address[]"}],"name":"sendBlockhash","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"_destinationChain","type":"string"},{"internalType":"address","name":"_destinationContract","type":"address"}],"name":"sendBlockhashEmergency","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"address","name":"destinationContract","type":"address"},{"internalType":"address","name":"recipient","type":"address"}],"name":"setRecipient","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"setRecipientMinValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"minValue","type":"uint256"}],"name":"setSendBlockHashMinValue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"minValue","type":"uint256"}],"name":"setSetRecipientMinValue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
6080604052660aa87bee53800060015566038d7ea4c6800060025534801561002657600080fd5b506040516114a23803806114a28339810160408190526100459161006a565b600080546001600160a01b0319166001600160a01b039290921691909117905561009a565b60006020828403121561007c57600080fd5b81516001600160a01b038116811461009357600080fd5b9392505050565b6113f9806100a96000396000f3fe6080604052600436106101025760003560e01c8063704b6c0211610095578063c0e7bcc411610064578063c0e7bcc4146102c1578063cd8bff33146102d7578063def64e9c14610304578063f20167d61461032c578063f851a4401461034c57600080fd5b8063704b6c021461023857806377ea078814610258578063829d08951461026b578063a59b4b3a1461028157600080fd5b80632dda65d8116100d15780632dda65d81461018f5780632e41b437146101d8578063310d7275146101f857806334cdf78d1461020b57600080fd5b8063086146d21461010e5780630cea40f6146101365780631ba50c0a146101675780632d674eca1461017c57600080fd5b3661010957005b600080fd5b34801561011a57600080fd5b5061012361036c565b6040519081526020015b60405180910390f35b34801561014257600080fd5b50610156610151366004610e14565b61038d565b60405161012d959493929190610e50565b61017a610175366004610ef9565b6105b7565b005b61017a61018a366004610ef9565b6106ab565b34801561019b57600080fd5b506101236101aa366004610f63565b6005602090815260009283526040909220815180830184018051928152908401929093019190912091525481565b3480156101e457600080fd5b5061017a6101f336600461101e565b610711565b61017a61020636600461107c565b610778565b34801561021757600080fd5b5061012361022636600461101e565b60046020526000908152604090205481565b34801561024457600080fd5b5061017a6102533660046110e8565b610811565b61017a61026636600461110a565b61088a565b34801561027757600080fd5b5061012360025481565b34801561028d57600080fd5b506102a9734f4495243837681061c4743b74b3eedf548d56a581565b6040516001600160a01b03909116815260200161012d565b3480156102cd57600080fd5b5061012360015481565b3480156102e357600080fd5b506101236102f236600461101e565b60036020526000908152604090205481565b34801561031057600080fd5b506102a9732d5d7d31f671f86c782533cc367f14109a08271281565b34801561033857600080fd5b5061017a61034736600461101e565b610a46565b34801561035857600080fd5b506000546102a9906001600160a01b031681565b600061037b62093a8042611185565b6103889062093a806111a7565b905090565b600080600061039a610dda565b60408051600b60208201526001600160a01b03891691810191909152600090819060600160408051601f198184030181528282528051602091820120908301526001600160a01b038a169082015260600160408051808303601f1901815291815281516020928301208086528151600c938101939093526001600160a01b038b1691830191909152915060009060600160408051601f19818403018152828252805160209182012090830152810189905260600160408051601f19818403018152828252805160209182012090830152016040516020818303038152906040528051906020012060001c905060005b60028110156104cf5761049c81836111da565b856104a88360016111da565b600681106104b8576104b86111c4565b6020020152806104c7816111ed565b915050610489565b60408051600960208201526001600160a01b038d169181019190915260009060600160408051601f198184030181528282528051602091820120908301526001600160a01b038d169082015260600160408051601f19818403018152828252805160209182012090830152016040516020818303038152906040528051906020012060001c9050600091505b60038210156105a15761056e82826111da565b8661057a8460036111da565b6006811061058a5761058a6111c4565b602002015281610599816111ed565b92505061055b565b50999a9899509697929650439550919350505050565b6001543410156105da5760405163f4e7be1760e01b815260040160405180910390fd5b60006105e461036c565b60008181526003602052604090205490915015801561060d57504261060b8261012c6111da565b105b1561064a5761061d600143611206565b60008281526004602052604090209040905561063a600143611206565b6000828152600360205260409020555b6000818152600360205260409020541580159061069457506000818152600560205260409081902090516106819086908690611219565b9081526020016040518091039020546000145b156106a5576106a582858584610aa6565b50505050565b6000546001600160a01b031633146106d6576040516325fc018b60e21b815260040160405180910390fd5b6001543410156106f95760405163f4e7be1760e01b815260040160405180910390fd5b600061070361036c565b90506106a582858584610aa6565b6000546001600160a01b0316331461073c576040516325fc018b60e21b815260040160405180910390fd5b60018190556040518181527f9015cb8d7f5c0565ae5e27ffe29afac978487692aa59d6224b7c9ea2e6c4b112906020015b60405180910390a150565b60015483906107889082906111a7565b3410156107a85760405163f4e7be1760e01b815260040160405180910390fd5b60005b81811015610809576108018686838181106107c8576107c86111c4565b90506020028101906107da9190611229565b8686858181106107ec576107ec6111c4565b905060200201602081019061017591906110e8565b6001016107ab565b505050505050565b6000546001600160a01b0316331461083c576040516325fc018b60e21b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c9060200161076d565b6002543410156108ad5760405163f4e7be1760e01b815260040160405180910390fd5b60006108c1836001600160a01b0316610c9e565b6040513360248201526001600160a01b038416604482015290915060009060640160408051601f198184030181529181526020820180516001600160e01b03166345e4203d60e11b17905251630c93e3bb60e01b8152909150732d5d7d31f671f86c782533cc367f14109a08271290630c93e3bb9034906109509030908b908b908990899033906004016112df565b6000604051808303818588803b15801561096957600080fd5b505af115801561097d573d6000803e3d6000fd5b5050604051631c92115f60e01b8152734f4495243837681061c4743b74b3eedf548d56a59350631c92115f92506109bf9150899089908790879060040161133f565b600060405180830381600087803b1580156109d957600080fd5b505af11580156109ed573d6000803e3d6000fd5b50505050826001600160a01b0316336001600160a01b03167f449039a365ffd6ef41683d137a4a0e5ac33a054540a39c82a0e7fcb549d9f1498888604051610a36929190611384565b60405180910390a3505050505050565b6000546001600160a01b03163314610a71576040516325fc018b60e21b815260040160405180910390fd5b60028190556040518181527ff8d9cc2e62c65a4c71d8e163b287488f9a1528d9ff440d8734de4ec8ff27b2c39060200161076d565b6000610aba856001600160a01b0316610c9e565b6000838152600360209081526040808320546004909252808320549051602481019290925260448201529192509060640160408051601f198184030181529181526020820180516001600160e01b03166306184ec160e11b17905251630c93e3bb60e01b8152909150732d5d7d31f671f86c782533cc367f14109a08271290630c93e3bb903490610b599030908a908a908990899033906004016112df565b6000604051808303818588803b158015610b7257600080fd5b505af1158015610b86573d6000803e3d6000fd5b5050604051631c92115f60e01b8152734f4495243837681061c4743b74b3eedf548d56a59350631c92115f9250610bc89150889088908790879060040161133f565b600060405180830381600087803b158015610be257600080fd5b505af1158015610bf6573d6000803e3d6000fd5b50505060008481526005602052604090819020905160019250610c1c9088908890611219565b90815260200160405180910390206000828254610c3991906111da565b909155505060008381526003602090815260408083205460049092529182902054915190917f6e2109b52f8ed2bd306d064301430858c39d43f66214166a54e5be7ba16d5c3f91610c8e9190899089906113a0565b60405180910390a2505050505050565b6060610ca982610d47565b6028602282019081209192507f4040404040404040404040404040404040404040404040404040404040404040917f888888888888888888888888888888888888888888888888888888888888888016601160f31b60005b82811a820281800152600181019060121901610d0157505050818151166000511660011c8151188152602081019050818151166020511660011c81511881525050919050565b6060610d5282610d6b565b8051613078825260020160011990910190815292915050565b60606040519050608081016040526f30313233343536373839616263646566600f526002810190506028815260208101600060288201528260601b925060005b808101820184821a600f81165160018301538060041c5182535050600181019060121901610dab575050919050565b6040518060c001604052806006906020820280368337509192915050565b80356001600160a01b0381168114610e0f57600080fd5b919050565b600080600060608486031215610e2957600080fd5b610e3284610df8565b9250610e4060208501610df8565b9150604084013590509250925092565b6001600160a01b03868116825285166020808301919091526040820185905261014082019060608301908560005b6006811015610e9b57815184529282019290820190600101610e7e565b50505050826101208301529695505050505050565b60008083601f840112610ec257600080fd5b50813567ffffffffffffffff811115610eda57600080fd5b602083019150836020828501011115610ef257600080fd5b9250929050565b600080600060408486031215610f0e57600080fd5b833567ffffffffffffffff811115610f2557600080fd5b610f3186828701610eb0565b9094509250610f44905060208501610df8565b90509250925092565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215610f7657600080fd5b82359150602083013567ffffffffffffffff80821115610f9557600080fd5b818501915085601f830112610fa957600080fd5b813581811115610fbb57610fbb610f4d565b604051601f8201601f19908116603f01168101908382118183101715610fe357610fe3610f4d565b81604052828152886020848701011115610ffc57600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b60006020828403121561103057600080fd5b5035919050565b60008083601f84011261104957600080fd5b50813567ffffffffffffffff81111561106157600080fd5b6020830191508360208260051b8501011115610ef257600080fd5b6000806000806040858703121561109257600080fd5b843567ffffffffffffffff808211156110aa57600080fd5b6110b688838901611037565b909650945060208701359150808211156110cf57600080fd5b506110dc87828801611037565b95989497509550505050565b6000602082840312156110fa57600080fd5b61110382610df8565b9392505050565b6000806000806060858703121561112057600080fd5b843567ffffffffffffffff81111561113757600080fd5b61114387828801610eb0565b9095509350611156905060208601610df8565b915061116460408601610df8565b905092959194509250565b634e487b7160e01b600052601160045260246000fd5b6000826111a257634e487b7160e01b600052601260045260246000fd5b500490565b80820281158282048414176111be576111be61116f565b92915050565b634e487b7160e01b600052603260045260246000fd5b808201808211156111be576111be61116f565b6000600182016111ff576111ff61116f565b5060010190565b818103818111156111be576111be61116f565b8183823760009101908152919050565b6000808335601e1984360301811261124057600080fd5b83018035915067ffffffffffffffff82111561125b57600080fd5b602001915036819003821315610ef257600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6000815180845260005b818110156112bf576020818501810151868301820152016112a3565b506000602082860101526020601f19601f83011685010191505092915050565b600060018060a01b03808916835260a0602084015261130260a08401888a611270565b83810360408501526113148188611299565b905083810360608501526113288187611299565b925050808416608084015250979650505050505050565b606081526000611353606083018688611270565b82810360208401526113658186611299565b905082810360408401526113798185611299565b979650505050505050565b602081526000611398602083018486611270565b949350505050565b8381526040602082015260006113ba604083018486611270565b9594505050505056fea26469706673582212203deb74e4d2843bfc8d6b09a3f7872b63ffe004b5e6497e47f92d1c7f7522ddb564736f6c634300081100330000000000000000000000000de5199779b43e13b3bec21e91117e18736bc1a8
Deployed Bytecode
0x6080604052600436106101025760003560e01c8063704b6c0211610095578063c0e7bcc411610064578063c0e7bcc4146102c1578063cd8bff33146102d7578063def64e9c14610304578063f20167d61461032c578063f851a4401461034c57600080fd5b8063704b6c021461023857806377ea078814610258578063829d08951461026b578063a59b4b3a1461028157600080fd5b80632dda65d8116100d15780632dda65d81461018f5780632e41b437146101d8578063310d7275146101f857806334cdf78d1461020b57600080fd5b8063086146d21461010e5780630cea40f6146101365780631ba50c0a146101675780632d674eca1461017c57600080fd5b3661010957005b600080fd5b34801561011a57600080fd5b5061012361036c565b6040519081526020015b60405180910390f35b34801561014257600080fd5b50610156610151366004610e14565b61038d565b60405161012d959493929190610e50565b61017a610175366004610ef9565b6105b7565b005b61017a61018a366004610ef9565b6106ab565b34801561019b57600080fd5b506101236101aa366004610f63565b6005602090815260009283526040909220815180830184018051928152908401929093019190912091525481565b3480156101e457600080fd5b5061017a6101f336600461101e565b610711565b61017a61020636600461107c565b610778565b34801561021757600080fd5b5061012361022636600461101e565b60046020526000908152604090205481565b34801561024457600080fd5b5061017a6102533660046110e8565b610811565b61017a61026636600461110a565b61088a565b34801561027757600080fd5b5061012360025481565b34801561028d57600080fd5b506102a9734f4495243837681061c4743b74b3eedf548d56a581565b6040516001600160a01b03909116815260200161012d565b3480156102cd57600080fd5b5061012360015481565b3480156102e357600080fd5b506101236102f236600461101e565b60036020526000908152604090205481565b34801561031057600080fd5b506102a9732d5d7d31f671f86c782533cc367f14109a08271281565b34801561033857600080fd5b5061017a61034736600461101e565b610a46565b34801561035857600080fd5b506000546102a9906001600160a01b031681565b600061037b62093a8042611185565b6103889062093a806111a7565b905090565b600080600061039a610dda565b60408051600b60208201526001600160a01b03891691810191909152600090819060600160408051601f198184030181528282528051602091820120908301526001600160a01b038a169082015260600160408051808303601f1901815291815281516020928301208086528151600c938101939093526001600160a01b038b1691830191909152915060009060600160408051601f19818403018152828252805160209182012090830152810189905260600160408051601f19818403018152828252805160209182012090830152016040516020818303038152906040528051906020012060001c905060005b60028110156104cf5761049c81836111da565b856104a88360016111da565b600681106104b8576104b86111c4565b6020020152806104c7816111ed565b915050610489565b60408051600960208201526001600160a01b038d169181019190915260009060600160408051601f198184030181528282528051602091820120908301526001600160a01b038d169082015260600160408051601f19818403018152828252805160209182012090830152016040516020818303038152906040528051906020012060001c9050600091505b60038210156105a15761056e82826111da565b8661057a8460036111da565b6006811061058a5761058a6111c4565b602002015281610599816111ed565b92505061055b565b50999a9899509697929650439550919350505050565b6001543410156105da5760405163f4e7be1760e01b815260040160405180910390fd5b60006105e461036c565b60008181526003602052604090205490915015801561060d57504261060b8261012c6111da565b105b1561064a5761061d600143611206565b60008281526004602052604090209040905561063a600143611206565b6000828152600360205260409020555b6000818152600360205260409020541580159061069457506000818152600560205260409081902090516106819086908690611219565b9081526020016040518091039020546000145b156106a5576106a582858584610aa6565b50505050565b6000546001600160a01b031633146106d6576040516325fc018b60e21b815260040160405180910390fd5b6001543410156106f95760405163f4e7be1760e01b815260040160405180910390fd5b600061070361036c565b90506106a582858584610aa6565b6000546001600160a01b0316331461073c576040516325fc018b60e21b815260040160405180910390fd5b60018190556040518181527f9015cb8d7f5c0565ae5e27ffe29afac978487692aa59d6224b7c9ea2e6c4b112906020015b60405180910390a150565b60015483906107889082906111a7565b3410156107a85760405163f4e7be1760e01b815260040160405180910390fd5b60005b81811015610809576108018686838181106107c8576107c86111c4565b90506020028101906107da9190611229565b8686858181106107ec576107ec6111c4565b905060200201602081019061017591906110e8565b6001016107ab565b505050505050565b6000546001600160a01b0316331461083c576040516325fc018b60e21b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c9060200161076d565b6002543410156108ad5760405163f4e7be1760e01b815260040160405180910390fd5b60006108c1836001600160a01b0316610c9e565b6040513360248201526001600160a01b038416604482015290915060009060640160408051601f198184030181529181526020820180516001600160e01b03166345e4203d60e11b17905251630c93e3bb60e01b8152909150732d5d7d31f671f86c782533cc367f14109a08271290630c93e3bb9034906109509030908b908b908990899033906004016112df565b6000604051808303818588803b15801561096957600080fd5b505af115801561097d573d6000803e3d6000fd5b5050604051631c92115f60e01b8152734f4495243837681061c4743b74b3eedf548d56a59350631c92115f92506109bf9150899089908790879060040161133f565b600060405180830381600087803b1580156109d957600080fd5b505af11580156109ed573d6000803e3d6000fd5b50505050826001600160a01b0316336001600160a01b03167f449039a365ffd6ef41683d137a4a0e5ac33a054540a39c82a0e7fcb549d9f1498888604051610a36929190611384565b60405180910390a3505050505050565b6000546001600160a01b03163314610a71576040516325fc018b60e21b815260040160405180910390fd5b60028190556040518181527ff8d9cc2e62c65a4c71d8e163b287488f9a1528d9ff440d8734de4ec8ff27b2c39060200161076d565b6000610aba856001600160a01b0316610c9e565b6000838152600360209081526040808320546004909252808320549051602481019290925260448201529192509060640160408051601f198184030181529181526020820180516001600160e01b03166306184ec160e11b17905251630c93e3bb60e01b8152909150732d5d7d31f671f86c782533cc367f14109a08271290630c93e3bb903490610b599030908a908a908990899033906004016112df565b6000604051808303818588803b158015610b7257600080fd5b505af1158015610b86573d6000803e3d6000fd5b5050604051631c92115f60e01b8152734f4495243837681061c4743b74b3eedf548d56a59350631c92115f9250610bc89150889088908790879060040161133f565b600060405180830381600087803b158015610be257600080fd5b505af1158015610bf6573d6000803e3d6000fd5b50505060008481526005602052604090819020905160019250610c1c9088908890611219565b90815260200160405180910390206000828254610c3991906111da565b909155505060008381526003602090815260408083205460049092529182902054915190917f6e2109b52f8ed2bd306d064301430858c39d43f66214166a54e5be7ba16d5c3f91610c8e9190899089906113a0565b60405180910390a2505050505050565b6060610ca982610d47565b6028602282019081209192507f4040404040404040404040404040404040404040404040404040404040404040917f888888888888888888888888888888888888888888888888888888888888888016601160f31b60005b82811a820281800152600181019060121901610d0157505050818151166000511660011c8151188152602081019050818151166020511660011c81511881525050919050565b6060610d5282610d6b565b8051613078825260020160011990910190815292915050565b60606040519050608081016040526f30313233343536373839616263646566600f526002810190506028815260208101600060288201528260601b925060005b808101820184821a600f81165160018301538060041c5182535050600181019060121901610dab575050919050565b6040518060c001604052806006906020820280368337509192915050565b80356001600160a01b0381168114610e0f57600080fd5b919050565b600080600060608486031215610e2957600080fd5b610e3284610df8565b9250610e4060208501610df8565b9150604084013590509250925092565b6001600160a01b03868116825285166020808301919091526040820185905261014082019060608301908560005b6006811015610e9b57815184529282019290820190600101610e7e565b50505050826101208301529695505050505050565b60008083601f840112610ec257600080fd5b50813567ffffffffffffffff811115610eda57600080fd5b602083019150836020828501011115610ef257600080fd5b9250929050565b600080600060408486031215610f0e57600080fd5b833567ffffffffffffffff811115610f2557600080fd5b610f3186828701610eb0565b9094509250610f44905060208501610df8565b90509250925092565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215610f7657600080fd5b82359150602083013567ffffffffffffffff80821115610f9557600080fd5b818501915085601f830112610fa957600080fd5b813581811115610fbb57610fbb610f4d565b604051601f8201601f19908116603f01168101908382118183101715610fe357610fe3610f4d565b81604052828152886020848701011115610ffc57600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b60006020828403121561103057600080fd5b5035919050565b60008083601f84011261104957600080fd5b50813567ffffffffffffffff81111561106157600080fd5b6020830191508360208260051b8501011115610ef257600080fd5b6000806000806040858703121561109257600080fd5b843567ffffffffffffffff808211156110aa57600080fd5b6110b688838901611037565b909650945060208701359150808211156110cf57600080fd5b506110dc87828801611037565b95989497509550505050565b6000602082840312156110fa57600080fd5b61110382610df8565b9392505050565b6000806000806060858703121561112057600080fd5b843567ffffffffffffffff81111561113757600080fd5b61114387828801610eb0565b9095509350611156905060208601610df8565b915061116460408601610df8565b905092959194509250565b634e487b7160e01b600052601160045260246000fd5b6000826111a257634e487b7160e01b600052601260045260246000fd5b500490565b80820281158282048414176111be576111be61116f565b92915050565b634e487b7160e01b600052603260045260246000fd5b808201808211156111be576111be61116f565b6000600182016111ff576111ff61116f565b5060010190565b818103818111156111be576111be61116f565b8183823760009101908152919050565b6000808335601e1984360301811261124057600080fd5b83018035915067ffffffffffffffff82111561125b57600080fd5b602001915036819003821315610ef257600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6000815180845260005b818110156112bf576020818501810151868301820152016112a3565b506000602082860101526020601f19601f83011685010191505092915050565b600060018060a01b03808916835260a0602084015261130260a08401888a611270565b83810360408501526113148188611299565b905083810360608501526113288187611299565b925050808416608084015250979650505050505050565b606081526000611353606083018688611270565b82810360208401526113658186611299565b905082810360408401526113798185611299565b979650505050505050565b602081526000611398602083018486611270565b949350505050565b8381526040602082015260006113ba604083018486611270565b9594505050505056fea26469706673582212203deb74e4d2843bfc8d6b09a3f7872b63ffe004b5e6497e47f92d1c7f7522ddb564736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000de5199779b43e13b3bec21e91117e18736bc1a8
-----Decoded View---------------
Arg [0] : _admin (address): 0x0dE5199779b43E13B3Bec21e91117E18736BC1A8
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000000de5199779b43e13b3bec21e91117e18736bc1a8
Deployed Bytecode Sourcemap
53192:8813:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61844:121;;;;;;;;;;;;;:::i;:::-;;;160:25:1;;;148:2;133:18;61844:121:0;;;;;;;;60794:967;;;;;;;;;;-1:-1:-1;60794:967:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;:::i;55302:727::-;;;;;;:::i;:::-;;:::i;:::-;;56985:383;;;;;;:::i;:::-;;:::i;53793:71::-;;;;;;;;;;-1:-1:-1;53793:71:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59792:217;;;;;;;;;;-1:-1:-1;59792:217:0;;;;;:::i;:::-;;:::i;56296:452::-;;;;;;:::i;:::-;;:::i;53740:46::-;;;;;;;;;;-1:-1:-1;53740:46:0;;;;;:::i;:::-;;;;;;;;;;;;;;60441:163;;;;;;;;;;-1:-1:-1;60441:163:0;;;;;:::i;:::-;;:::i;58826:832::-;;;;;;:::i;:::-;;:::i;53610:54::-;;;;;;;;;;;;;;;;53348:83;;;;;;;;;;;;53389:42;53348:83;;;;;-1:-1:-1;;;;;5978:32:1;;;5960:51;;5948:2;5933:18;53348:83:0;5814:203:1;53535:55:0;;;;;;;;;;;;;;;;53686:47;;;;;;;;;;-1:-1:-1;53686:47:0;;;;;:::i;:::-;;;;;;;;;;;;;;53438:88;;;;;;;;;;;;53484:42;53438:88;;60142:214;;;;;;;;;;-1:-1:-1;60142:214:0;;;;;:::i;:::-;;:::i;53319:20::-;;;;;;;;;;-1:-1:-1;53319:20:0;;;;-1:-1:-1;;;;;53319:20:0;;;61844:121;61893:7;61921:25;61939:7;61921:15;:25;:::i;:::-;:35;;61949:7;61921:35;:::i;:::-;61913:44;;61844:121;:::o;60794:967::-;60922:7;60931;60940;60949:28;;:::i;:::-;61074:21;;;61085:2;61074:21;;;6730:36:1;-1:-1:-1;;;;;6802:32:1;;6782:18;;;6775:60;;;;60979:7:0;;;;6703:18:1;;61074:21:0;;;-1:-1:-1;;61074:21:0;;;;;;;;;61064:32;;61074:21;61064:32;;;;61053:52;;;7020:25:1;-1:-1:-1;;;;;7081:32:1;;7061:18;;;7054:60;6993:18;;61053:52:0;;;;;;-1:-1:-1;;61053:52:0;;;;;;61043:63;;61053:52;61043:63;;;;61118:36;;;61269:22;;61280:2;61269:22;;;6730:36:1;;;;-1:-1:-1;;;;;6802:32:1;;6782:18;;;6775:60;;;;61043:63:0;-1:-1:-1;61035:72:0;;6703:18:1;;61269:22:0;;;-1:-1:-1;;61269:22:0;;;;;;;;;61259:33;;61269:22;61259:33;;;;61248:52;;;7728:25:1;7769:18;;7762:34;;;7701:18;;61248:52:0;;;-1:-1:-1;;61248:52:0;;;;;;;;;61238:63;;61248:52;61238:63;;;;61227:75;;;160:25:1;133:18;61227:75:0;;;;;;;;;;;;61217:86;;;;;;61209:95;;61165:139;;61315:9;61335:95;61351:1;61347;:5;61335:95;;;61394:24;61417:1;61394:20;:24;:::i;:::-;61374:10;61385:5;61389:1;61385;:5;:::i;:::-;61374:17;;;;;;;:::i;:::-;;;;:44;61354:3;;;;:::i;:::-;;;;61335:95;;;61547:20;;;61558:1;61547:20;;;6730:36:1;-1:-1:-1;;;;;6802:32:1;;6782:18;;;6775:60;;;;61442:29:0;;6703:18:1;;61547:20:0;;;-1:-1:-1;;61547:20:0;;;;;;;;;61537:31;;61547:20;61537:31;;;;61526:51;;;7020:25:1;-1:-1:-1;;;;;7081:32:1;;7061:18;;;7054:60;6993:18;;61526:51:0;;;-1:-1:-1;;61526:51:0;;;;;;;;;61516:62;;61526:51;61516:62;;;;61505:74;;;160:25:1;133:18;61505:74:0;;;;;;;;;;;;61495:85;;;;;;61487:94;;61442:139;;61601:1;61597:5;;61592:96;61608:1;61604;:5;61592:96;;;61651:25;61675:1;61651:21;:25;:::i;:::-;61631:10;61642:5;61646:1;61642;:5;:::i;:::-;61631:17;;;;;;;:::i;:::-;;;;:45;61611:3;;;;:::i;:::-;;;;61592:96;;;-1:-1:-1;61706:5:0;;61713:6;;-1:-1:-1;61721:5:0;;60794:967;;-1:-1:-1;61740:12:0;;-1:-1:-1;60794:967:0;;-1:-1:-1;;;;60794:967:0:o;55302:727::-;55432:21;;55420:9;:33;55416:61;;;55462:15;;-1:-1:-1;;;55462:15:0;;;;;;;;;;;55416:61;55488:21;55512:18;:16;:18::i;:::-;55590:27;;;;:12;:27;;;;;;55488:42;;-1:-1:-1;55590:32:0;:79;;;;-1:-1:-1;55654:15:0;55626:25;:13;55642:9;55626:25;:::i;:::-;:43;55590:79;55586:229;;;55725:16;55740:1;55725:12;:16;:::i;:::-;55686:26;;;;:11;:26;;;;;55715:27;;55686:56;;55787:16;55802:1;55787:12;:16;:::i;:::-;55757:27;;;;:12;:27;;;;;:46;55586:229;55831:27;;;;:12;:27;;;;;;:32;;;;:92;;-1:-1:-1;55867:32:0;;;;:17;:32;;;;;;;:51;;;;55900:17;;;;55867:51;:::i;:::-;;;;;;;;;;;;;;55922:1;55867:56;55831:92;55827:195;;;55940:70;55955:20;55977:17;;55996:13;55940:14;:70::i;:::-;55405:624;55302:727;;;:::o;56985:383::-;57128:5;;-1:-1:-1;;;;;57128:5:0;57114:10;:19;57110:44;;57142:12;;-1:-1:-1;;;57142:12:0;;;;;;;;;;;57110:44;57181:21;;57169:9;:33;57165:61;;;57211:15;;-1:-1:-1;;;57211:15:0;;;;;;;;;;;57165:61;57237:21;57261:18;:16;:18::i;:::-;57237:42;;57290:70;57305:20;57327:17;;57346:13;57290:14;:70::i;59792:217::-;59882:5;;-1:-1:-1;;;;;59882:5:0;59868:10;:19;59864:44;;59896:12;;-1:-1:-1;;;59896:12:0;;;;;;;;;;;59864:44;59919:21;:32;;;59967:34;;160:25:1;;;59967:34:0;;148:2:1;133:18;59967:34:0;;;;;;;;59792:217;:::o;56296:452::-;56496:21;;56444:18;;56496:30;;56444:18;;56496:30;:::i;:::-;56484:9;:42;56480:70;;;56535:15;;-1:-1:-1;;;56535:15:0;;;;;;;;;;;56480:70;56566:9;56561:180;56581:6;56577:1;:10;56561:180;;;56605:62;56619:18;;56638:1;56619:21;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;56642;;56664:1;56642:24;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;56605:62::-;56711:3;;56561:180;;;;56416:332;56296:452;;;;:::o;60441:163::-;60513:5;;-1:-1:-1;;;;;60513:5:0;60499:10;:19;60495:44;;60527:12;;-1:-1:-1;;;60527:12:0;;;;;;;;;;;60495:44;60550:5;:14;;-1:-1:-1;;;;;;60550:14:0;-1:-1:-1;;;;;60550:14:0;;;;;;;;60580:16;;5960:51:1;;;60580:16:0;;5948:2:1;5933:18;60580:16:0;5814:203:1;58826:832:0;58974:20;;58962:9;:32;58958:60;;;59003:15;;-1:-1:-1;;;59003:15:0;;;;;;;;;;;58958:60;59029:34;59066:43;:19;-1:-1:-1;;;;;59066:41:0;;:43::i;:::-;59160:79;;59217:10;59160:79;;;9523:34:1;-1:-1:-1;;;;;9593:15:1;;9573:18;;;9566:43;59029:80:0;;-1:-1:-1;59120:20:0;;9458:18:1;;59160:79:0;;;-1:-1:-1;;59160:79:0;;;;;;;;;;;;;;-1:-1:-1;;;;;59160:79:0;-1:-1:-1;;;59160:79:0;;;59252:198;-1:-1:-1;;;59252:198:0;;59160:79;;-1:-1:-1;53484:42:0;;59252:72;;59332:9;;59252:198;;59369:4;;59376:16;;;;59394:20;;59160:79;;59425:10;;59252:198;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;59463:116:0;;-1:-1:-1;;;59463:116:0;;53389:42;;-1:-1:-1;59463:43:0;;-1:-1:-1;59463:116:0;;-1:-1:-1;59521:16:0;;;;59539:20;;59561:7;;59463:116;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59622:9;-1:-1:-1;;;;;59597:53:0;59610:10;-1:-1:-1;;;;;59597:53:0;;59633:16;;59597:53;;;;;;;:::i;:::-;;;;;;;;58947:711;;58826:832;;;;:::o;60142:214::-;60231:5;;-1:-1:-1;;;;;60231:5:0;60217:10;:19;60213:44;;60245:12;;-1:-1:-1;;;60245:12:0;;;;;;;;;;;60213:44;60268:20;:31;;;60315:33;;160:25:1;;;60315:33:0;;148:2:1;133:18;60315:33:0;14:177:1;57635:955:0;57765:34;57802:43;:19;-1:-1:-1;;;;;57802:41:0;;:43::i;:::-;57856:20;57952:27;;;:12;:27;;;;;;;;;57981:11;:26;;;;;;;57892:116;;;;;7728:25:1;;;;7769:18;;;7762:34;57765:80:0;;-1:-1:-1;57856:20:0;7701:18:1;;57892:116:0;;;-1:-1:-1;;57892:116:0;;;;;;;;;;;;;;-1:-1:-1;;;;;57892:116:0;-1:-1:-1;;;57892:116:0;;;58113:190;-1:-1:-1;;;58113:190:0;;57892:116;;-1:-1:-1;53484:42:0;;58113:72;;58193:9;;58113:190;;58226:4;;58233:16;;;;58251:20;;57892:116;;58282:10;;58113:190;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;58316:92:0;;-1:-1:-1;;;58316:92:0;;53389:42;;-1:-1:-1;58316:43:0;;-1:-1:-1;58316:92:0;;-1:-1:-1;58360:16:0;;;;58378:20;;58400:7;;58316:92;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;58421:32:0;;;;:17;:32;;;;;;;:50;;58475:1;;-1:-1:-1;58421:50:0;;58454:16;;;;58421:50;:::i;:::-;;;;;;;;;;;;;;:55;;;;;;;:::i;:::-;;;;-1:-1:-1;;58508:27:0;;;;:12;:27;;;;;;;;;58537:11;:26;;;;;;;;58494:88;;58508:27;;58494:88;;;;58537:26;58565:16;;;;58494:88;:::i;:::-;;;;;;;;57754:836;;57635:955;;;;:::o;10408:854::-;10477:17;10513:18;10525:5;10513:11;:18::i;:::-;10758:2;10708:4;10699:14;;10745:16;;;10507:24;;-1:-1:-1;10622:24:0;;10763:13;10741:36;-1:-1:-1;;;10637:1:0;10871:172;10939:15;;;10932:23;;10921:9;;;10914:42;10986:1;10979:9;;;-1:-1:-1;;11009:9:0;10871:172;11006:22;10875:14;;;11119:4;11115:1;11109:8;11105:19;11098:4;11092:11;11088:37;11085:1;11081:45;11077:1;11071:8;11067:60;11064:1;11057:71;11154:4;11151:1;11147:12;11142:17;;11235:4;11231:1;11225:8;11221:19;11214:4;11208:11;11204:37;11201:1;11197:45;11193:1;11187:8;11183:60;11180:1;11173:71;;;10408:854;;;:::o;11426:445::-;11485:17;11521:26;11541:5;11521:19;:26::i;:::-;11647:10;;11710:6;11698:19;;11659:1;11643:18;-1:-1:-1;;11764:11:0;;;11810:22;;;11764:11;11426:445;-1:-1:-1;;11426:445:0:o;12012:1327::-;12079:17;12190:4;12184:11;12177:18;;12523:4;12518:3;12514:14;12508:4;12501:28;12617:34;12611:4;12604:48;12684:1;12679:3;12675:11;12668:18;;12712:2;12707:3;12700:15;12749:4;12744:3;12740:14;12787:1;12782:2;12779:1;12775:10;12768:21;12822:5;12818:2;12814:14;12805:23;;13029:1;13014:307;13080:1;13077;13073:9;13070:1;13066:17;13121:5;13118:1;13113:14;13180:2;13174:4;13170:13;13164:20;13160:1;13157;13153:9;13145:40;13227:4;13224:1;13220:12;13214:19;13211:1;13203:31;-1:-1:-1;;13264:1:0;13257:9;;;-1:-1:-1;;13287:9:0;13014:307;13284:22;13018:14;;12012:1327;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;:::o;196:173:1:-;264:20;;-1:-1:-1;;;;;313:31:1;;303:42;;293:70;;359:1;356;349:12;293:70;196:173;;;:::o;374:328::-;451:6;459;467;520:2;508:9;499:7;495:23;491:32;488:52;;;536:1;533;526:12;488:52;559:29;578:9;559:29;:::i;:::-;549:39;;607:38;641:2;630:9;626:18;607:38;:::i;:::-;597:48;;692:2;681:9;677:18;664:32;654:42;;374:328;;;;;:::o;707:824::-;-1:-1:-1;;;;;1068:15:1;;;1050:34;;1141:15;;1103:2;1121:18;;;1114:43;;;;1188:2;1173:18;;1166:34;;;999:3;984:19;;;1235:2;1220:18;;;1280:6;957:4;1314:167;1328:4;1325:1;1322:11;1314:167;;;1387:13;;1375:26;;1421:12;;;;1456:15;;;;1348:1;1341:9;1314:167;;;1318:3;;;;1518:6;1512:3;1501:9;1497:19;1490:35;707:824;;;;;;;;:::o;1536:348::-;1588:8;1598:6;1652:3;1645:4;1637:6;1633:17;1629:27;1619:55;;1670:1;1667;1660:12;1619:55;-1:-1:-1;1693:20:1;;1736:18;1725:30;;1722:50;;;1768:1;1765;1758:12;1722:50;1805:4;1797:6;1793:17;1781:29;;1857:3;1850:4;1841:6;1833;1829:19;1825:30;1822:39;1819:59;;;1874:1;1871;1864:12;1819:59;1536:348;;;;;:::o;1889:485::-;1969:6;1977;1985;2038:2;2026:9;2017:7;2013:23;2009:32;2006:52;;;2054:1;2051;2044:12;2006:52;2094:9;2081:23;2127:18;2119:6;2116:30;2113:50;;;2159:1;2156;2149:12;2113:50;2198:59;2249:7;2240:6;2229:9;2225:22;2198:59;:::i;:::-;2276:8;;-1:-1:-1;2172:85:1;-1:-1:-1;2330:38:1;;-1:-1:-1;2364:2:1;2349:18;;2330:38;:::i;:::-;2320:48;;1889:485;;;;;:::o;2379:127::-;2440:10;2435:3;2431:20;2428:1;2421:31;2471:4;2468:1;2461:15;2495:4;2492:1;2485:15;2511:990;2589:6;2597;2650:2;2638:9;2629:7;2625:23;2621:32;2618:52;;;2666:1;2663;2656:12;2618:52;2702:9;2689:23;2679:33;;2763:2;2752:9;2748:18;2735:32;2786:18;2827:2;2819:6;2816:14;2813:34;;;2843:1;2840;2833:12;2813:34;2881:6;2870:9;2866:22;2856:32;;2926:7;2919:4;2915:2;2911:13;2907:27;2897:55;;2948:1;2945;2938:12;2897:55;2984:2;2971:16;3006:2;3002;2999:10;2996:36;;;3012:18;;:::i;:::-;3087:2;3081:9;3055:2;3141:13;;-1:-1:-1;;3137:22:1;;;3161:2;3133:31;3129:40;3117:53;;;3185:18;;;3205:22;;;3182:46;3179:72;;;3231:18;;:::i;:::-;3271:10;3267:2;3260:22;3306:2;3298:6;3291:18;3346:7;3341:2;3336;3332;3328:11;3324:20;3321:33;3318:53;;;3367:1;3364;3357:12;3318:53;3423:2;3418;3414;3410:11;3405:2;3397:6;3393:15;3380:46;3468:1;3463:2;3458;3450:6;3446:15;3442:24;3435:35;3489:6;3479:16;;;;;;;2511:990;;;;;:::o;3506:180::-;3565:6;3618:2;3606:9;3597:7;3593:23;3589:32;3586:52;;;3634:1;3631;3624:12;3586:52;-1:-1:-1;3657:23:1;;3506:180;-1:-1:-1;3506:180:1:o;3691:375::-;3762:8;3772:6;3826:3;3819:4;3811:6;3807:17;3803:27;3793:55;;3844:1;3841;3834:12;3793:55;-1:-1:-1;3867:20:1;;3910:18;3899:30;;3896:50;;;3942:1;3939;3932:12;3896:50;3979:4;3971:6;3967:17;3955:29;;4039:3;4032:4;4022:6;4019:1;4015:14;4007:6;4003:27;3999:38;3996:47;3993:67;;;4056:1;4053;4046:12;4071:801;4205:6;4213;4221;4229;4282:2;4270:9;4261:7;4257:23;4253:32;4250:52;;;4298:1;4295;4288:12;4250:52;4338:9;4325:23;4367:18;4408:2;4400:6;4397:14;4394:34;;;4424:1;4421;4414:12;4394:34;4463:78;4533:7;4524:6;4513:9;4509:22;4463:78;:::i;:::-;4560:8;;-1:-1:-1;4437:104:1;-1:-1:-1;4648:2:1;4633:18;;4620:32;;-1:-1:-1;4664:16:1;;;4661:36;;;4693:1;4690;4683:12;4661:36;;4732:80;4804:7;4793:8;4782:9;4778:24;4732:80;:::i;:::-;4071:801;;;;-1:-1:-1;4831:8:1;-1:-1:-1;;;;4071:801:1:o;5059:186::-;5118:6;5171:2;5159:9;5150:7;5146:23;5142:32;5139:52;;;5187:1;5184;5177:12;5139:52;5210:29;5229:9;5210:29;:::i;:::-;5200:39;5059:186;-1:-1:-1;;;5059:186:1:o;5250:559::-;5339:6;5347;5355;5363;5416:2;5404:9;5395:7;5391:23;5387:32;5384:52;;;5432:1;5429;5422:12;5384:52;5472:9;5459:23;5505:18;5497:6;5494:30;5491:50;;;5537:1;5534;5527:12;5491:50;5576:59;5627:7;5618:6;5607:9;5603:22;5576:59;:::i;:::-;5654:8;;-1:-1:-1;5550:85:1;-1:-1:-1;5708:38:1;;-1:-1:-1;5742:2:1;5727:18;;5708:38;:::i;:::-;5698:48;;5765:38;5799:2;5788:9;5784:18;5765:38;:::i;:::-;5755:48;;5250:559;;;;;;;:::o;6022:127::-;6083:10;6078:3;6074:20;6071:1;6064:31;6114:4;6111:1;6104:15;6138:4;6135:1;6128:15;6154:217;6194:1;6220;6210:132;;6264:10;6259:3;6255:20;6252:1;6245:31;6299:4;6296:1;6289:15;6327:4;6324:1;6317:15;6210:132;-1:-1:-1;6356:9:1;;6154:217::o;6376:168::-;6449:9;;;6480;;6497:15;;;6491:22;;6477:37;6467:71;;6518:18;;:::i;:::-;6376:168;;;;:::o;7125:127::-;7186:10;7181:3;7177:20;7174:1;7167:31;7217:4;7214:1;7207:15;7241:4;7238:1;7231:15;7807:125;7872:9;;;7893:10;;;7890:36;;;7906:18;;:::i;7937:135::-;7976:3;7997:17;;;7994:43;;8017:18;;:::i;:::-;-1:-1:-1;8064:1:1;8053:13;;7937:135::o;8373:128::-;8440:9;;;8461:11;;;8458:37;;;8475:18;;:::i;8506:273::-;8691:6;8683;8678:3;8665:33;8647:3;8717:16;;8742:13;;;8717:16;8506:273;-1:-1:-1;8506:273:1:o;8784:522::-;8862:4;8868:6;8928:11;8915:25;9022:2;9018:7;9007:8;8991:14;8987:29;8983:43;8963:18;8959:68;8949:96;;9041:1;9038;9031:12;8949:96;9068:33;;9120:20;;;-1:-1:-1;9163:18:1;9152:30;;9149:50;;;9195:1;9192;9185:12;9149:50;9228:4;9216:17;;-1:-1:-1;9259:14:1;9255:27;;;9245:38;;9242:58;;;9296:1;9293;9286:12;9620:267;9709:6;9704:3;9697:19;9761:6;9754:5;9747:4;9742:3;9738:14;9725:43;-1:-1:-1;9813:1:1;9788:16;;;9806:4;9784:27;;;9777:38;;;;9869:2;9848:15;;;-1:-1:-1;;9844:29:1;9835:39;;;9831:50;;9620:267::o;9892:423::-;9934:3;9972:5;9966:12;9999:6;9994:3;9987:19;10024:1;10034:162;10048:6;10045:1;10042:13;10034:162;;;10110:4;10166:13;;;10162:22;;10156:29;10138:11;;;10134:20;;10127:59;10063:12;10034:162;;;10038:3;10241:1;10234:4;10225:6;10220:3;10216:16;10212:27;10205:38;10304:4;10297:2;10293:7;10288:2;10280:6;10276:15;10272:29;10267:3;10263:39;10259:50;10252:57;;;9892:423;;;;:::o;10320:772::-;10592:4;10638:1;10634;10629:3;10625:11;10621:19;10679:2;10671:6;10667:15;10656:9;10649:34;10719:3;10714:2;10703:9;10699:18;10692:31;10746:63;10804:3;10793:9;10789:19;10781:6;10773;10746:63;:::i;:::-;10857:9;10849:6;10845:22;10840:2;10829:9;10825:18;10818:50;10891:33;10917:6;10909;10891:33;:::i;:::-;10877:47;;10972:9;10964:6;10960:22;10955:2;10944:9;10940:18;10933:50;11000:33;11026:6;11018;11000:33;:::i;:::-;10992:41;;;11082:2;11074:6;11070:15;11064:3;11053:9;11049:19;11042:44;;10320:772;;;;;;;;;:::o;11097:571::-;11350:2;11339:9;11332:21;11313:4;11376:62;11434:2;11423:9;11419:18;11411:6;11403;11376:62;:::i;:::-;11486:9;11478:6;11474:22;11469:2;11458:9;11454:18;11447:50;11520:33;11546:6;11538;11520:33;:::i;:::-;11506:47;;11601:9;11593:6;11589:22;11584:2;11573:9;11569:18;11562:50;11629:33;11655:6;11647;11629:33;:::i;:::-;11621:41;11097:571;-1:-1:-1;;;;;;;11097:571:1:o;11673:247::-;11832:2;11821:9;11814:21;11795:4;11852:62;11910:2;11899:9;11895:18;11887:6;11879;11852:62;:::i;:::-;11844:70;11673:247;-1:-1:-1;;;;11673:247:1:o;12178:318::-;12365:6;12354:9;12347:25;12408:2;12403;12392:9;12388:18;12381:30;12328:4;12428:62;12486:2;12475:9;12471:18;12463:6;12455;12428:62;:::i;:::-;12420:70;12178:318;-1:-1:-1;;;;;12178:318:1:o
Swarm Source
ipfs://3deb74e4d2843bfc8d6b09a3f7872b63ffe004b5e6497e47f92d1c7f7522ddb5
Loading...
Loading
Loading...
Loading
Net Worth in USD
$5.97
Net Worth in ETH
0.003
Token Allocations
ETH
100.00%
Multichain Portfolio | 32 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| ETH | 100.00% | $1,989.06 | 0.003 | $5.97 |
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.