Source Code
Overview
GLMR Balance
GLMR Value
$0.00| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 5387497 | 730 days ago | 0 GLMR | ||||
| 5387497 | 730 days ago | 0 GLMR | ||||
| 5387497 | 730 days ago | 0 GLMR | ||||
| 5387497 | 730 days ago | 0 GLMR | ||||
| 5387497 | 730 days ago | 0 GLMR | ||||
| 5387497 | 730 days ago | 0 GLMR | ||||
| 5387497 | 730 days ago | 0 GLMR | ||||
| 5387497 | 730 days ago | 0 GLMR | ||||
| 5387497 | 730 days ago | 0 GLMR | ||||
| 5387497 | 730 days ago | 0 GLMR | ||||
| 5387497 | 730 days ago | 0 GLMR | ||||
| 5387497 | 730 days ago | 0 GLMR | ||||
| 5387497 | 730 days ago | 0 GLMR | ||||
| 5387497 | 730 days ago | 0 GLMR | ||||
| 5387497 | 730 days ago | 0 GLMR | ||||
| 5387496 | 730 days ago | 0 GLMR | ||||
| 5387496 | 730 days ago | 0 GLMR | ||||
| 5387496 | 730 days ago | 0 GLMR | ||||
| 5387496 | 730 days ago | 0 GLMR | ||||
| 5387496 | 730 days ago | 0 GLMR | ||||
| 5387496 | 730 days ago | 0 GLMR | ||||
| 5387496 | 730 days ago | 0 GLMR | ||||
| 5387496 | 730 days ago | 0 GLMR | ||||
| 5387496 | 730 days ago | 0 GLMR | ||||
| 5387496 | 730 days ago | 0 GLMR |
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
Implementation
Compiler Version
v0.8.4+commit.c7e474f2
Contract Source Code (Solidity)
/**
*Submitted for verification at moonbeam.moonscan.io on 2022-07-21
*/
// SPDX-License-Identifier: Apache 2
// File: contracts/Structs.sol
// contracts/Structs.sol
pragma solidity ^0.8.0;
interface Structs {
struct Provider {
uint16 chainId;
uint16 governanceChainId;
bytes32 governanceContract;
}
struct GuardianSet {
address[] keys;
uint32 expirationTime;
}
struct Signature {
bytes32 r;
bytes32 s;
uint8 v;
uint8 guardianIndex;
}
struct VM {
uint8 version;
uint32 timestamp;
uint32 nonce;
uint16 emitterChainId;
bytes32 emitterAddress;
uint64 sequence;
uint8 consistencyLevel;
bytes payload;
uint32 guardianSetIndex;
Signature[] signatures;
bytes32 hash;
}
}
// File: contracts/libraries/external/BytesLib.sol
/*
* @title Solidity Bytes Arrays Utils
* @author Gonçalo Sá <[email protected]>
*
* @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.
* The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.
*/
pragma solidity >=0.8.0 <0.9.0;
library BytesLib {
function concat(
bytes memory _preBytes,
bytes memory _postBytes
)
internal
pure
returns (bytes memory)
{
bytes memory tempBytes;
assembly {
// Get a location of some free memory and store it in tempBytes as
// Solidity does for memory variables.
tempBytes := mload(0x40)
// Store the length of the first bytes array at the beginning of
// the memory for tempBytes.
let length := mload(_preBytes)
mstore(tempBytes, length)
// Maintain a memory counter for the current write location in the
// temp bytes array by adding the 32 bytes for the array length to
// the starting location.
let mc := add(tempBytes, 0x20)
// Stop copying when the memory counter reaches the length of the
// first bytes array.
let end := add(mc, length)
for {
// Initialize a copy counter to the start of the _preBytes data,
// 32 bytes into its memory.
let cc := add(_preBytes, 0x20)
} lt(mc, end) {
// Increase both counters by 32 bytes each iteration.
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
// Write the _preBytes data into the tempBytes memory 32 bytes
// at a time.
mstore(mc, mload(cc))
}
// Add the length of _postBytes to the current length of tempBytes
// and store it as the new length in the first 32 bytes of the
// tempBytes memory.
length := mload(_postBytes)
mstore(tempBytes, add(length, mload(tempBytes)))
// Move the memory counter back from a multiple of 0x20 to the
// actual end of the _preBytes data.
mc := end
// Stop copying when the memory counter reaches the new combined
// length of the arrays.
end := add(mc, length)
for {
let cc := add(_postBytes, 0x20)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
// Update the free-memory pointer by padding our last write location
// to 32 bytes: add 31 bytes to the end of tempBytes to move to the
// next 32 byte block, then round down to the nearest multiple of
// 32. If the sum of the length of the two arrays is zero then add
// one before rounding down to leave a blank 32 bytes (the length block with 0).
mstore(0x40, and(
add(add(end, iszero(add(length, mload(_preBytes)))), 31),
not(31) // Round down to the nearest 32 bytes.
))
}
return tempBytes;
}
function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {
assembly {
// Read the first 32 bytes of _preBytes storage, which is the length
// of the array. (We don't need to use the offset into the slot
// because arrays use the entire slot.)
let fslot := sload(_preBytes.slot)
// Arrays of 31 bytes or less have an even value in their slot,
// while longer arrays have an odd value. The actual length is
// the slot divided by two for odd values, and the lowest order
// byte divided by two for even values.
// If the slot is even, bitwise and the slot with 255 and divide by
// two to get the length. If the slot is odd, bitwise and the slot
// with -1 and divide by two.
let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
let mlength := mload(_postBytes)
let newlength := add(slength, mlength)
// slength can contain both the length and contents of the array
// if length < 32 bytes so let's prepare for that
// v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
switch add(lt(slength, 32), lt(newlength, 32))
case 2 {
// Since the new array still fits in the slot, we just need to
// update the contents of the slot.
// uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length
sstore(
_preBytes.slot,
// all the modifications to the slot are inside this
// next block
add(
// we can just add to the slot contents because the
// bytes we want to change are the LSBs
fslot,
add(
mul(
div(
// load the bytes from memory
mload(add(_postBytes, 0x20)),
// zero all bytes to the right
exp(0x100, sub(32, mlength))
),
// and now shift left the number of bytes to
// leave space for the length in the slot
exp(0x100, sub(32, newlength))
),
// increase length by the double of the memory
// bytes length
mul(mlength, 2)
)
)
)
}
case 1 {
// The stored value fits in the slot, but the combined value
// will exceed it.
// get the keccak hash to get the contents of the array
mstore(0x0, _preBytes.slot)
let sc := add(keccak256(0x0, 0x20), div(slength, 32))
// save new length
sstore(_preBytes.slot, add(mul(newlength, 2), 1))
// The contents of the _postBytes array start 32 bytes into
// the structure. Our first read should obtain the `submod`
// bytes that can fit into the unused space in the last word
// of the stored array. To get this, we read 32 bytes starting
// from `submod`, so the data we read overlaps with the array
// contents by `submod` bytes. Masking the lowest-order
// `submod` bytes allows us to add that value directly to the
// stored value.
let submod := sub(32, slength)
let mc := add(_postBytes, submod)
let end := add(_postBytes, mlength)
let mask := sub(exp(0x100, submod), 1)
sstore(
sc,
add(
and(
fslot,
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
),
and(mload(mc), mask)
)
)
for {
mc := add(mc, 0x20)
sc := add(sc, 1)
} lt(mc, end) {
sc := add(sc, 1)
mc := add(mc, 0x20)
} {
sstore(sc, mload(mc))
}
mask := exp(0x100, sub(mc, end))
sstore(sc, mul(div(mload(mc), mask), mask))
}
default {
// get the keccak hash to get the contents of the array
mstore(0x0, _preBytes.slot)
// Start copying to the last used word of the stored array.
let sc := add(keccak256(0x0, 0x20), div(slength, 32))
// save new length
sstore(_preBytes.slot, add(mul(newlength, 2), 1))
// Copy over the first `submod` bytes of the new data as in
// case 1 above.
let slengthmod := mod(slength, 32)
let mlengthmod := mod(mlength, 32)
let submod := sub(32, slengthmod)
let mc := add(_postBytes, submod)
let end := add(_postBytes, mlength)
let mask := sub(exp(0x100, submod), 1)
sstore(sc, add(sload(sc), and(mload(mc), mask)))
for {
sc := add(sc, 1)
mc := add(mc, 0x20)
} lt(mc, end) {
sc := add(sc, 1)
mc := add(mc, 0x20)
} {
sstore(sc, mload(mc))
}
mask := exp(0x100, sub(mc, end))
sstore(sc, mul(div(mload(mc), mask), mask))
}
}
}
function slice(
bytes memory _bytes,
uint256 _start,
uint256 _length
)
internal
pure
returns (bytes memory)
{
require(_length + 31 >= _length, "slice_overflow");
require(_bytes.length >= _start + _length, "slice_outOfBounds");
bytes memory tempBytes;
assembly {
switch iszero(_length)
case 0 {
// Get a location of some free memory and store it in tempBytes as
// Solidity does for memory variables.
tempBytes := mload(0x40)
// The first word of the slice result is potentially a partial
// word read from the original array. To read it, we calculate
// the length of that partial word and start copying that many
// bytes into the array. The first word we copy will start with
// data we don't care about, but the last `lengthmod` bytes will
// land at the beginning of the contents of the new array. When
// we're done copying, we overwrite the full first word with
// the actual length of the slice.
let lengthmod := and(_length, 31)
// The multiplication in the next line is necessary
// because when slicing multiples of 32 bytes (lengthmod == 0)
// the following copy loop was copying the origin's length
// and then ending prematurely not copying everything it should.
let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
let end := add(mc, _length)
for {
// The multiplication in the next line has the same exact purpose
// as the one above.
let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
mstore(tempBytes, _length)
//update free-memory pointer
//allocating the array padded to 32 bytes like the compiler does now
mstore(0x40, and(add(mc, 31), not(31)))
}
//if we want a zero-length slice let's just return a zero-length array
default {
tempBytes := mload(0x40)
//zero out the 32 bytes slice we are about to return
//we need to do it because Solidity does not garbage collect
mstore(tempBytes, 0)
mstore(0x40, add(tempBytes, 0x20))
}
}
return tempBytes;
}
function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {
require(_bytes.length >= _start + 20, "toAddress_outOfBounds");
address tempAddress;
assembly {
tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)
}
return tempAddress;
}
function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {
require(_bytes.length >= _start + 1 , "toUint8_outOfBounds");
uint8 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x1), _start))
}
return tempUint;
}
function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {
require(_bytes.length >= _start + 2, "toUint16_outOfBounds");
uint16 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x2), _start))
}
return tempUint;
}
function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {
require(_bytes.length >= _start + 4, "toUint32_outOfBounds");
uint32 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x4), _start))
}
return tempUint;
}
function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {
require(_bytes.length >= _start + 8, "toUint64_outOfBounds");
uint64 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x8), _start))
}
return tempUint;
}
function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {
require(_bytes.length >= _start + 12, "toUint96_outOfBounds");
uint96 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0xc), _start))
}
return tempUint;
}
function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {
require(_bytes.length >= _start + 16, "toUint128_outOfBounds");
uint128 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x10), _start))
}
return tempUint;
}
function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {
require(_bytes.length >= _start + 32, "toUint256_outOfBounds");
uint256 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x20), _start))
}
return tempUint;
}
function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {
require(_bytes.length >= _start + 32, "toBytes32_outOfBounds");
bytes32 tempBytes32;
assembly {
tempBytes32 := mload(add(add(_bytes, 0x20), _start))
}
return tempBytes32;
}
function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {
bool success = true;
assembly {
let length := mload(_preBytes)
// if lengths don't match the arrays are not equal
switch eq(length, mload(_postBytes))
case 1 {
// cb is a circuit breaker in the for loop since there's
// no said feature for inline assembly loops
// cb = 1 - don't breaker
// cb = 0 - break
let cb := 1
let mc := add(_preBytes, 0x20)
let end := add(mc, length)
for {
let cc := add(_postBytes, 0x20)
// the next line is the loop condition:
// while(uint256(mc < end) + cb == 2)
} eq(add(lt(mc, end), cb), 2) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
// if any of these checks fails then arrays are not equal
if iszero(eq(mload(mc), mload(cc))) {
// unsuccess:
success := 0
cb := 0
}
}
}
default {
// unsuccess:
success := 0
}
}
return success;
}
function equalStorage(
bytes storage _preBytes,
bytes memory _postBytes
)
internal
view
returns (bool)
{
bool success = true;
assembly {
// we know _preBytes_offset is 0
let fslot := sload(_preBytes.slot)
// Decode the length of the stored array like in concatStorage().
let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
let mlength := mload(_postBytes)
// if lengths don't match the arrays are not equal
switch eq(slength, mlength)
case 1 {
// slength can contain both the length and contents of the array
// if length < 32 bytes so let's prepare for that
// v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
if iszero(iszero(slength)) {
switch lt(slength, 32)
case 1 {
// blank the last byte which is the length
fslot := mul(div(fslot, 0x100), 0x100)
if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {
// unsuccess:
success := 0
}
}
default {
// cb is a circuit breaker in the for loop since there's
// no said feature for inline assembly loops
// cb = 1 - don't breaker
// cb = 0 - break
let cb := 1
// get the keccak hash to get the contents of the array
mstore(0x0, _preBytes.slot)
let sc := keccak256(0x0, 0x20)
let mc := add(_postBytes, 0x20)
let end := add(mc, mlength)
// the next line is the loop condition:
// while(uint256(mc < end) + cb == 2)
for {} eq(add(lt(mc, end), cb), 2) {
sc := add(sc, 1)
mc := add(mc, 0x20)
} {
if iszero(eq(sload(sc), mload(mc))) {
// unsuccess:
success := 0
cb := 0
}
}
}
}
}
default {
// unsuccess:
success := 0
}
}
return success;
}
}
// File: contracts/GovernanceStructs.sol
// contracts/GovernanceStructs.sol
pragma solidity ^0.8.0;
/**
* @dev `GovernanceStructs` defines a set of structs and parsing functions
* for minimal struct validation
*/
contract GovernanceStructs {
using BytesLib for bytes;
enum GovernanceAction {
UpgradeContract,
UpgradeGuardianset
}
struct ContractUpgrade {
bytes32 module;
uint8 action;
uint16 chain;
address newContract;
}
struct GuardianSetUpgrade {
bytes32 module;
uint8 action;
uint16 chain;
Structs.GuardianSet newGuardianSet;
uint32 newGuardianSetIndex;
}
struct SetMessageFee {
bytes32 module;
uint8 action;
uint16 chain;
uint256 messageFee;
}
struct TransferFees {
bytes32 module;
uint8 action;
uint16 chain;
uint256 amount;
bytes32 recipient;
}
/// @dev Parse a contract upgrade (action 1) with minimal validation
function parseContractUpgrade(bytes memory encodedUpgrade) public pure returns (ContractUpgrade memory cu) {
uint index = 0;
cu.module = encodedUpgrade.toBytes32(index);
index += 32;
cu.action = encodedUpgrade.toUint8(index);
index += 1;
require(cu.action == 1, "invalid ContractUpgrade");
cu.chain = encodedUpgrade.toUint16(index);
index += 2;
cu.newContract = address(uint160(uint256(encodedUpgrade.toBytes32(index))));
index += 32;
require(encodedUpgrade.length == index, "invalid ContractUpgrade");
}
/// @dev Parse a guardianSet upgrade (action 2) with minimal validation
function parseGuardianSetUpgrade(bytes memory encodedUpgrade) public pure returns (GuardianSetUpgrade memory gsu) {
uint index = 0;
gsu.module = encodedUpgrade.toBytes32(index);
index += 32;
gsu.action = encodedUpgrade.toUint8(index);
index += 1;
require(gsu.action == 2, "invalid GuardianSetUpgrade");
gsu.chain = encodedUpgrade.toUint16(index);
index += 2;
gsu.newGuardianSetIndex = encodedUpgrade.toUint32(index);
index += 4;
uint8 guardianLength = encodedUpgrade.toUint8(index);
index += 1;
gsu.newGuardianSet = Structs.GuardianSet({
keys : new address[](guardianLength),
expirationTime : 0
});
for(uint i = 0; i < guardianLength; i++) {
gsu.newGuardianSet.keys[i] = encodedUpgrade.toAddress(index);
index += 20;
}
require(encodedUpgrade.length == index, "invalid GuardianSetUpgrade");
}
/// @dev Parse a setMessageFee (action 3) with minimal validation
function parseSetMessageFee(bytes memory encodedSetMessageFee) public pure returns (SetMessageFee memory smf) {
uint index = 0;
smf.module = encodedSetMessageFee.toBytes32(index);
index += 32;
smf.action = encodedSetMessageFee.toUint8(index);
index += 1;
require(smf.action == 3, "invalid SetMessageFee");
smf.chain = encodedSetMessageFee.toUint16(index);
index += 2;
smf.messageFee = encodedSetMessageFee.toUint256(index);
index += 32;
require(encodedSetMessageFee.length == index, "invalid SetMessageFee");
}
/// @dev Parse a transferFees (action 4) with minimal validation
function parseTransferFees(bytes memory encodedTransferFees) public pure returns (TransferFees memory tf) {
uint index = 0;
tf.module = encodedTransferFees.toBytes32(index);
index += 32;
tf.action = encodedTransferFees.toUint8(index);
index += 1;
require(tf.action == 4, "invalid TransferFees");
tf.chain = encodedTransferFees.toUint16(index);
index += 2;
tf.amount = encodedTransferFees.toUint256(index);
index += 32;
tf.recipient = encodedTransferFees.toBytes32(index);
index += 32;
require(encodedTransferFees.length == index, "invalid TransferFees");
}
}
// File: contracts/State.sol
// contracts/State.sol
pragma solidity ^0.8.0;
contract Events {
event LogGuardianSetChanged(
uint32 oldGuardianIndex,
uint32 newGuardianIndex
);
event LogMessagePublished(
address emitter_address,
uint32 nonce,
bytes payload
);
}
contract Storage {
struct WormholeState {
Structs.Provider provider;
// Mapping of guardian_set_index => guardian set
mapping(uint32 => Structs.GuardianSet) guardianSets;
// Current active guardian set index
uint32 guardianSetIndex;
// Period for which a guardian set stays active after it has been replaced
uint32 guardianSetExpiry;
// Sequence numbers per emitter
mapping(address => uint64) sequences;
// Mapping of consumed governance actions
mapping(bytes32 => bool) consumedGovernanceActions;
// Mapping of initialized implementations
mapping(address => bool) initializedImplementations;
uint256 messageFee;
}
}
contract State {
Storage.WormholeState _state;
}
// File: contracts/Getters.sol
// contracts/Getters.sol
pragma solidity ^0.8.0;
contract Getters is State {
function getGuardianSet(uint32 index) public view returns (Structs.GuardianSet memory) {
return _state.guardianSets[index];
}
function getCurrentGuardianSetIndex() public view returns (uint32) {
return _state.guardianSetIndex;
}
function getGuardianSetExpiry() public view returns (uint32) {
return _state.guardianSetExpiry;
}
function governanceActionIsConsumed(bytes32 hash) public view returns (bool) {
return _state.consumedGovernanceActions[hash];
}
function isInitialized(address impl) public view returns (bool) {
return _state.initializedImplementations[impl];
}
function chainId() public view returns (uint16) {
return _state.provider.chainId;
}
function governanceChainId() public view returns (uint16){
return _state.provider.governanceChainId;
}
function governanceContract() public view returns (bytes32){
return _state.provider.governanceContract;
}
function messageFee() public view returns (uint256) {
return _state.messageFee;
}
function nextSequence(address emitter) public view returns (uint64) {
return _state.sequences[emitter];
}
}
// File: contracts/Messages.sol
// contracts/Messages.sol
pragma solidity ^0.8.0;
pragma experimental ABIEncoderV2;
contract Messages is Getters {
using BytesLib for bytes;
/// @dev parseAndVerifyVM serves to parse an encodedVM and wholy validate it for consumption
function parseAndVerifyVM(bytes calldata encodedVM) public view returns (Structs.VM memory vm, bool valid, string memory reason) {
vm = parseVM(encodedVM);
(valid, reason) = verifyVM(vm);
}
/**
* @dev `verifyVM` serves to validate an arbitrary vm against a valid Guardian set
* - it aims to make sure the VM is for a known guardianSet
* - it aims to ensure the guardianSet is not expired
* - it aims to ensure the VM has reached quorum
* - it aims to verify the signatures provided against the guardianSet
*/
function verifyVM(Structs.VM memory vm) public view returns (bool valid, string memory reason) {
/// @dev Obtain the current guardianSet for the guardianSetIndex provided
Structs.GuardianSet memory guardianSet = getGuardianSet(vm.guardianSetIndex);
/**
* @dev Checks whether the guardianSet has zero keys
* WARNING: This keys check is critical to ensure the guardianSet has keys present AND to ensure
* that guardianSet key size doesn't fall to zero and negatively impact quorum assessment. If guardianSet
* key length is 0 and vm.signatures length is 0, this could compromise the integrity of both vm and
* signature verification.
*/
if(guardianSet.keys.length == 0){
return (false, "invalid guardian set");
}
/// @dev Checks if VM guardian set index matches the current index (unless the current set is expired).
if(vm.guardianSetIndex != getCurrentGuardianSetIndex() && guardianSet.expirationTime < block.timestamp){
return (false, "guardian set has expired");
}
/**
* @dev We're using a fixed point number transformation with 1 decimal to deal with rounding.
* WARNING: This quorum check is critical to assessing whether we have enough Guardian signatures to validate a VM
* if making any changes to this, obtain additional peer review. If guardianSet key length is 0 and
* vm.signatures length is 0, this could compromise the integrity of both vm and signature verification.
*/
if (vm.signatures.length < quorum(guardianSet.keys.length)){
return (false, "no quorum");
}
/// @dev Verify the proposed vm.signatures against the guardianSet
(bool signaturesValid, string memory invalidReason) = verifySignatures(vm.hash, vm.signatures, guardianSet);
if(!signaturesValid){
return (false, invalidReason);
}
/// If we are here, we've validated the VM is a valid multi-sig that matches the guardianSet.
return (true, "");
}
/**
* @dev verifySignatures serves to validate arbitrary sigatures against an arbitrary guardianSet
* - it intentionally does not solve for expectations within guardianSet (you should use verifyVM if you need these protections)
* - it intentioanlly does not solve for quorum (you should use verifyVM if you need these protections)
* - it intentionally returns true when signatures is an empty set (you should use verifyVM if you need these protections)
*/
function verifySignatures(bytes32 hash, Structs.Signature[] memory signatures, Structs.GuardianSet memory guardianSet) public pure returns (bool valid, string memory reason) {
uint8 lastIndex = 0;
for (uint i = 0; i < signatures.length; i++) {
Structs.Signature memory sig = signatures[i];
/// Ensure that provided signature indices are ascending only
require(i == 0 || sig.guardianIndex > lastIndex, "signature indices must be ascending");
lastIndex = sig.guardianIndex;
/// Check to see if the signer of the signature does not match a specific Guardian key at the provided index
if(ecrecover(hash, sig.v, sig.r, sig.s) != guardianSet.keys[sig.guardianIndex]){
return (false, "VM signature invalid");
}
}
/// If we are here, we've validated that the provided signatures are valid for the provided guardianSet
return (true, "");
}
/**
* @dev parseVM serves to parse an encodedVM into a vm struct
* - it intentionally performs no validation functions, it simply parses raw into a struct
*/
function parseVM(bytes memory encodedVM) public pure virtual returns (Structs.VM memory vm) {
uint index = 0;
vm.version = encodedVM.toUint8(index);
index += 1;
require(vm.version == 1, "VM version incompatible");
vm.guardianSetIndex = encodedVM.toUint32(index);
index += 4;
// Parse Signatures
uint256 signersLen = encodedVM.toUint8(index);
index += 1;
vm.signatures = new Structs.Signature[](signersLen);
for (uint i = 0; i < signersLen; i++) {
vm.signatures[i].guardianIndex = encodedVM.toUint8(index);
index += 1;
vm.signatures[i].r = encodedVM.toBytes32(index);
index += 32;
vm.signatures[i].s = encodedVM.toBytes32(index);
index += 32;
vm.signatures[i].v = encodedVM.toUint8(index) + 27;
index += 1;
}
// Hash the body
bytes memory body = encodedVM.slice(index, encodedVM.length - index);
vm.hash = keccak256(abi.encodePacked(keccak256(body)));
// Parse the body
vm.timestamp = encodedVM.toUint32(index);
index += 4;
vm.nonce = encodedVM.toUint32(index);
index += 4;
vm.emitterChainId = encodedVM.toUint16(index);
index += 2;
vm.emitterAddress = encodedVM.toBytes32(index);
index += 32;
vm.sequence = encodedVM.toUint64(index);
index += 8;
vm.consistencyLevel = encodedVM.toUint8(index);
index += 1;
vm.payload = encodedVM.slice(index, encodedVM.length - index);
}
/**
* @dev quorum serves solely to determine the number of signatures required to acheive quorum
*/
function quorum(uint numGuardians) public pure virtual returns (uint numSignaturesRequiredForQuorum) {
return ((numGuardians * 2) / 3) + 1;
}
}
// File: contracts/Setters.sol
// contracts/Setters.sol
pragma solidity ^0.8.0;
contract Setters is State {
function updateGuardianSetIndex(uint32 newIndex) internal {
_state.guardianSetIndex = newIndex;
}
function expireGuardianSet(uint32 index) internal {
_state.guardianSets[index].expirationTime = uint32(block.timestamp) + 86400;
}
function storeGuardianSet(Structs.GuardianSet memory set, uint32 index) internal {
_state.guardianSets[index] = set;
}
function setInitialized(address implementatiom) internal {
_state.initializedImplementations[implementatiom] = true;
}
function setGovernanceActionConsumed(bytes32 hash) internal {
_state.consumedGovernanceActions[hash] = true;
}
function setChainId(uint16 chainId) internal {
_state.provider.chainId = chainId;
}
function setGovernanceChainId(uint16 chainId) internal {
_state.provider.governanceChainId = chainId;
}
function setGovernanceContract(bytes32 governanceContract) internal {
_state.provider.governanceContract = governanceContract;
}
function setMessageFee(uint256 newFee) internal {
_state.messageFee = newFee;
}
function setNextSequence(address emitter, uint64 sequence) internal {
_state.sequences[emitter] = sequence;
}
}
// File: @openzeppelin/contracts/proxy/beacon/IBeacon.sol
pragma solidity ^0.8.0;
/**
* @dev This is the interface that {BeaconProxy} expects of its beacon.
*/
interface IBeacon {
/**
* @dev Must return an address that can be used as a delegate call target.
*
* {BeaconProxy} will check that this address is a contract.
*/
function implementation() external view returns (address);
}
// File: @openzeppelin/contracts/utils/Address.sol
pragma solidity ^0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
// File: @openzeppelin/contracts/utils/StorageSlot.sol
pragma solidity ^0.8.0;
/**
* @dev Library for reading and writing primitive types to specific storage slots.
*
* Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
* This library helps with reading and writing to such slots without the need for inline assembly.
*
* The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
*
* Example usage to set ERC1967 implementation slot:
* ```
* contract ERC1967 {
* bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
*
* function _getImplementation() internal view returns (address) {
* return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
* }
*
* function _setImplementation(address newImplementation) internal {
* require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
* StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
* }
* }
* ```
*
* _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._
*/
library StorageSlot {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 value;
}
/**
* @dev Returns an `AddressSlot` with member `value` located at `slot`.
*/
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `BooleanSlot` with member `value` located at `slot`.
*/
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
*/
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Uint256Slot` with member `value` located at `slot`.
*/
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
assembly {
r.slot := slot
}
}
}
// File: @openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol
pragma solidity ^0.8.2;
/**
* @dev This abstract contract provides getters and event emitting update functions for
* https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
*
* _Available since v4.1._
*
* @custom:oz-upgrades-unsafe-allow delegatecall
*/
abstract contract ERC1967Upgrade {
// This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1
bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;
/**
* @dev Storage slot with the address of the current implementation.
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/**
* @dev Emitted when the implementation is upgraded.
*/
event Upgraded(address indexed implementation);
/**
* @dev Returns the current implementation address.
*/
function _getImplementation() internal view returns (address) {
return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 implementation slot.
*/
function _setImplementation(address newImplementation) private {
require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
}
/**
* @dev Perform implementation upgrade
*
* Emits an {Upgraded} event.
*/
function _upgradeTo(address newImplementation) internal {
_setImplementation(newImplementation);
emit Upgraded(newImplementation);
}
/**
* @dev Perform implementation upgrade with additional setup call.
*
* Emits an {Upgraded} event.
*/
function _upgradeToAndCall(
address newImplementation,
bytes memory data,
bool forceCall
) internal {
_upgradeTo(newImplementation);
if (data.length > 0 || forceCall) {
Address.functionDelegateCall(newImplementation, data);
}
}
/**
* @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.
*
* Emits an {Upgraded} event.
*/
function _upgradeToAndCallSecure(
address newImplementation,
bytes memory data,
bool forceCall
) internal {
address oldImplementation = _getImplementation();
// Initial upgrade and setup call
_setImplementation(newImplementation);
if (data.length > 0 || forceCall) {
Address.functionDelegateCall(newImplementation, data);
}
// Perform rollback test if not already in progress
StorageSlot.BooleanSlot storage rollbackTesting = StorageSlot.getBooleanSlot(_ROLLBACK_SLOT);
if (!rollbackTesting.value) {
// Trigger rollback using upgradeTo from the new implementation
rollbackTesting.value = true;
Address.functionDelegateCall(
newImplementation,
abi.encodeWithSignature("upgradeTo(address)", oldImplementation)
);
rollbackTesting.value = false;
// Check rollback was effective
require(oldImplementation == _getImplementation(), "ERC1967Upgrade: upgrade breaks further upgrades");
// Finally reset to the new implementation and log the upgrade
_upgradeTo(newImplementation);
}
}
/**
* @dev Storage slot with the admin of the contract.
* This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
/**
* @dev Emitted when the admin account has changed.
*/
event AdminChanged(address previousAdmin, address newAdmin);
/**
* @dev Returns the current admin.
*/
function _getAdmin() internal view returns (address) {
return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 admin slot.
*/
function _setAdmin(address newAdmin) private {
require(newAdmin != address(0), "ERC1967: new admin is the zero address");
StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;
}
/**
* @dev Changes the admin of the proxy.
*
* Emits an {AdminChanged} event.
*/
function _changeAdmin(address newAdmin) internal {
emit AdminChanged(_getAdmin(), newAdmin);
_setAdmin(newAdmin);
}
/**
* @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
* This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.
*/
bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;
/**
* @dev Emitted when the beacon is upgraded.
*/
event BeaconUpgraded(address indexed beacon);
/**
* @dev Returns the current beacon.
*/
function _getBeacon() internal view returns (address) {
return StorageSlot.getAddressSlot(_BEACON_SLOT).value;
}
/**
* @dev Stores a new beacon in the EIP1967 beacon slot.
*/
function _setBeacon(address newBeacon) private {
require(Address.isContract(newBeacon), "ERC1967: new beacon is not a contract");
require(
Address.isContract(IBeacon(newBeacon).implementation()),
"ERC1967: beacon implementation is not a contract"
);
StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;
}
/**
* @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does
* not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).
*
* Emits a {BeaconUpgraded} event.
*/
function _upgradeBeaconToAndCall(
address newBeacon,
bytes memory data,
bool forceCall
) internal {
_setBeacon(newBeacon);
emit BeaconUpgraded(newBeacon);
if (data.length > 0 || forceCall) {
Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);
}
}
}
// File: contracts/Governance.sol
// contracts/Governance.sol
pragma solidity ^0.8.0;
/**
* @dev `Governance` defines a means to enacting changes to the core bridge contract,
* guardianSets, message fees, and transfer fees
*/
abstract contract Governance is GovernanceStructs, Messages, Setters, ERC1967Upgrade {
event ContractUpgraded(address indexed oldContract, address indexed newContract);
event GuardianSetAdded(uint32 indexed index);
// "Core" (left padded)
bytes32 constant module = 0x00000000000000000000000000000000000000000000000000000000436f7265;
/**
* @dev Upgrades a contract via Governance VAA/VM
*/
function submitContractUpgrade(bytes memory _vm) public {
Structs.VM memory vm = parseVM(_vm);
// Verify the VAA is valid before processing it
(bool isValid, string memory reason) = verifyGovernanceVM(vm);
require(isValid, reason);
GovernanceStructs.ContractUpgrade memory upgrade = parseContractUpgrade(vm.payload);
// Verify the VAA is for this module
require(upgrade.module == module, "Invalid Module");
// Verify the VAA is for this chain
require(upgrade.chain == chainId(), "Invalid Chain");
// Record the governance action as consumed
setGovernanceActionConsumed(vm.hash);
// Upgrades the implementation to the new contract
upgradeImplementation(upgrade.newContract);
}
/**
* @dev Sets a `messageFee` via Governance VAA/VM
*/
function submitSetMessageFee(bytes memory _vm) public {
Structs.VM memory vm = parseVM(_vm);
// Verify the VAA is valid before processing it
(bool isValid, string memory reason) = verifyGovernanceVM(vm);
require(isValid, reason);
GovernanceStructs.SetMessageFee memory upgrade = parseSetMessageFee(vm.payload);
// Verify the VAA is for this module
require(upgrade.module == module, "Invalid Module");
// Verify the VAA is for this chain
require(upgrade.chain == chainId(), "Invalid Chain");
// Record the governance action as consumed to prevent reentry
setGovernanceActionConsumed(vm.hash);
// Updates the messageFee
setMessageFee(upgrade.messageFee);
}
/**
* @dev Deploys a new `guardianSet` via Governance VAA/VM
*/
function submitNewGuardianSet(bytes memory _vm) public {
Structs.VM memory vm = parseVM(_vm);
// Verify the VAA is valid before processing it
(bool isValid, string memory reason) = verifyGovernanceVM(vm);
require(isValid, reason);
GovernanceStructs.GuardianSetUpgrade memory upgrade = parseGuardianSetUpgrade(vm.payload);
// Verify the VAA is for this module
require(upgrade.module == module, "invalid Module");
// Verify the VAA is for this chain
require(upgrade.chain == chainId() || upgrade.chain == 0, "invalid Chain");
// Verify the Guardian Set keys are not empty, this guards
// against the accidential upgrade to an empty GuardianSet
require(upgrade.newGuardianSet.keys.length > 0, "new guardian set is empty");
// Verify that the index is incrementing via a predictable +1 pattern
require(upgrade.newGuardianSetIndex == getCurrentGuardianSetIndex() + 1, "index must increase in steps of 1");
// Record the governance action as consumed to prevent reentry
setGovernanceActionConsumed(vm.hash);
// Trigger a time-based expiry of current guardianSet
expireGuardianSet(getCurrentGuardianSetIndex());
// Add the new guardianSet to guardianSets
storeGuardianSet(upgrade.newGuardianSet, upgrade.newGuardianSetIndex);
// Makes the new guardianSet effective
updateGuardianSetIndex(upgrade.newGuardianSetIndex);
}
/**
* @dev Submits transfer fees to the recipient via Governance VAA/VM
*/
function submitTransferFees(bytes memory _vm) public {
Structs.VM memory vm = parseVM(_vm);
// Verify the VAA is valid before processing it
(bool isValid, string memory reason) = verifyGovernanceVM(vm);
require(isValid, reason);
// Obtains the transfer from the VAA payload
GovernanceStructs.TransferFees memory transfer = parseTransferFees(vm.payload);
// Verify the VAA is for this module
require(transfer.module == module, "invalid Module");
// Verify the VAA is for this chain
require(transfer.chain == chainId() || transfer.chain == 0, "invalid Chain");
// Record the governance action as consumed to prevent reentry
setGovernanceActionConsumed(vm.hash);
// Obtains the recipient address to be paid transfer fees
address payable recipient = payable(address(uint160(uint256(transfer.recipient))));
// Transfers transfer fees to the recipient
recipient.transfer(transfer.amount);
}
/**
* @dev Upgrades the `currentImplementation` with a `newImplementation`
*/
function upgradeImplementation(address newImplementation) internal {
address currentImplementation = _getImplementation();
_upgradeTo(newImplementation);
// Call initialize function of the new implementation
(bool success, bytes memory reason) = newImplementation.delegatecall(abi.encodeWithSignature("initialize()"));
require(success, string(reason));
emit ContractUpgraded(currentImplementation, newImplementation);
}
/**
* @dev Verifies a Governance VAA/VM is valid
*/
function verifyGovernanceVM(Structs.VM memory vm) internal view returns (bool, string memory){
// Verify the VAA is valid
(bool isValid, string memory reason) = verifyVM(vm);
if (!isValid){
return (false, reason);
}
// only current guardianset can sign governance packets
if (vm.guardianSetIndex != getCurrentGuardianSetIndex()) {
return (false, "not signed by current guardian set");
}
// Verify the VAA is from the governance chain (Solana)
if (uint16(vm.emitterChainId) != governanceChainId()) {
return (false, "wrong governance chain");
}
// Verify the emitter contract is the governance contract (0x4 left padded)
if (vm.emitterAddress != governanceContract()) {
return (false, "wrong governance contract");
}
// Verify this governance action hasn't already been
// consumed to prevent reentry and replay
if (governanceActionIsConsumed(vm.hash)){
return (false, "governance action already consumed");
}
// Confirm the governance VAA/VM is valid
return (true, "");
}
}
// File: contracts/Implementation.sol
// contracts/Implementation.sol
pragma solidity ^0.8.0;
contract Implementation is Governance {
event LogMessagePublished(address indexed sender, uint64 sequence, uint32 nonce, bytes payload, uint8 consistencyLevel);
// Publish a message to be attested by the Wormhole network
function publishMessage(
uint32 nonce,
bytes memory payload,
uint8 consistencyLevel
) public payable returns (uint64 sequence) {
// check fee
require(msg.value == messageFee(), "invalid fee");
sequence = useSequence(msg.sender);
// emit log
emit LogMessagePublished(msg.sender, sequence, nonce, payload, consistencyLevel);
}
function useSequence(address emitter) internal returns (uint64 sequence) {
sequence = nextSequence(emitter);
setNextSequence(emitter, sequence + 1);
}
function initialize() initializer public virtual {
// this function needs to be exposed for an upgrade to pass
}
modifier initializer() {
address implementation = ERC1967Upgrade._getImplementation();
require(
!isInitialized(implementation),
"already initialized"
);
setInitialized(implementation);
_;
}
fallback() external payable {revert("unsupported");}
receive() external payable {revert("the Wormhole contract does not accept assets");}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldContract","type":"address"},{"indexed":true,"internalType":"address","name":"newContract","type":"address"}],"name":"ContractUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"index","type":"uint32"}],"name":"GuardianSetAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint64","name":"sequence","type":"uint64"},{"indexed":false,"internalType":"uint32","name":"nonce","type":"uint32"},{"indexed":false,"internalType":"bytes","name":"payload","type":"bytes"},{"indexed":false,"internalType":"uint8","name":"consistencyLevel","type":"uint8"}],"name":"LogMessagePublished","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"chainId","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentGuardianSetIndex","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"index","type":"uint32"}],"name":"getGuardianSet","outputs":[{"components":[{"internalType":"address[]","name":"keys","type":"address[]"},{"internalType":"uint32","name":"expirationTime","type":"uint32"}],"internalType":"struct Structs.GuardianSet","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGuardianSetExpiry","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"governanceActionIsConsumed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governanceChainId","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governanceContract","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"impl","type":"address"}],"name":"isInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"messageFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"emitter","type":"address"}],"name":"nextSequence","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedVM","type":"bytes"}],"name":"parseAndVerifyVM","outputs":[{"components":[{"internalType":"uint8","name":"version","type":"uint8"},{"internalType":"uint32","name":"timestamp","type":"uint32"},{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"uint16","name":"emitterChainId","type":"uint16"},{"internalType":"bytes32","name":"emitterAddress","type":"bytes32"},{"internalType":"uint64","name":"sequence","type":"uint64"},{"internalType":"uint8","name":"consistencyLevel","type":"uint8"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"uint32","name":"guardianSetIndex","type":"uint32"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"uint8","name":"guardianIndex","type":"uint8"}],"internalType":"struct Structs.Signature[]","name":"signatures","type":"tuple[]"},{"internalType":"bytes32","name":"hash","type":"bytes32"}],"internalType":"struct Structs.VM","name":"vm","type":"tuple"},{"internalType":"bool","name":"valid","type":"bool"},{"internalType":"string","name":"reason","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedUpgrade","type":"bytes"}],"name":"parseContractUpgrade","outputs":[{"components":[{"internalType":"bytes32","name":"module","type":"bytes32"},{"internalType":"uint8","name":"action","type":"uint8"},{"internalType":"uint16","name":"chain","type":"uint16"},{"internalType":"address","name":"newContract","type":"address"}],"internalType":"struct GovernanceStructs.ContractUpgrade","name":"cu","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedUpgrade","type":"bytes"}],"name":"parseGuardianSetUpgrade","outputs":[{"components":[{"internalType":"bytes32","name":"module","type":"bytes32"},{"internalType":"uint8","name":"action","type":"uint8"},{"internalType":"uint16","name":"chain","type":"uint16"},{"components":[{"internalType":"address[]","name":"keys","type":"address[]"},{"internalType":"uint32","name":"expirationTime","type":"uint32"}],"internalType":"struct Structs.GuardianSet","name":"newGuardianSet","type":"tuple"},{"internalType":"uint32","name":"newGuardianSetIndex","type":"uint32"}],"internalType":"struct GovernanceStructs.GuardianSetUpgrade","name":"gsu","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedSetMessageFee","type":"bytes"}],"name":"parseSetMessageFee","outputs":[{"components":[{"internalType":"bytes32","name":"module","type":"bytes32"},{"internalType":"uint8","name":"action","type":"uint8"},{"internalType":"uint16","name":"chain","type":"uint16"},{"internalType":"uint256","name":"messageFee","type":"uint256"}],"internalType":"struct GovernanceStructs.SetMessageFee","name":"smf","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedTransferFees","type":"bytes"}],"name":"parseTransferFees","outputs":[{"components":[{"internalType":"bytes32","name":"module","type":"bytes32"},{"internalType":"uint8","name":"action","type":"uint8"},{"internalType":"uint16","name":"chain","type":"uint16"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"recipient","type":"bytes32"}],"internalType":"struct GovernanceStructs.TransferFees","name":"tf","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedVM","type":"bytes"}],"name":"parseVM","outputs":[{"components":[{"internalType":"uint8","name":"version","type":"uint8"},{"internalType":"uint32","name":"timestamp","type":"uint32"},{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"uint16","name":"emitterChainId","type":"uint16"},{"internalType":"bytes32","name":"emitterAddress","type":"bytes32"},{"internalType":"uint64","name":"sequence","type":"uint64"},{"internalType":"uint8","name":"consistencyLevel","type":"uint8"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"uint32","name":"guardianSetIndex","type":"uint32"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"uint8","name":"guardianIndex","type":"uint8"}],"internalType":"struct Structs.Signature[]","name":"signatures","type":"tuple[]"},{"internalType":"bytes32","name":"hash","type":"bytes32"}],"internalType":"struct Structs.VM","name":"vm","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"uint8","name":"consistencyLevel","type":"uint8"}],"name":"publishMessage","outputs":[{"internalType":"uint64","name":"sequence","type":"uint64"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"numGuardians","type":"uint256"}],"name":"quorum","outputs":[{"internalType":"uint256","name":"numSignaturesRequiredForQuorum","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"_vm","type":"bytes"}],"name":"submitContractUpgrade","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_vm","type":"bytes"}],"name":"submitNewGuardianSet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_vm","type":"bytes"}],"name":"submitSetMessageFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_vm","type":"bytes"}],"name":"submitTransferFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"uint8","name":"guardianIndex","type":"uint8"}],"internalType":"struct Structs.Signature[]","name":"signatures","type":"tuple[]"},{"components":[{"internalType":"address[]","name":"keys","type":"address[]"},{"internalType":"uint32","name":"expirationTime","type":"uint32"}],"internalType":"struct Structs.GuardianSet","name":"guardianSet","type":"tuple"}],"name":"verifySignatures","outputs":[{"internalType":"bool","name":"valid","type":"bool"},{"internalType":"string","name":"reason","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"uint8","name":"version","type":"uint8"},{"internalType":"uint32","name":"timestamp","type":"uint32"},{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"uint16","name":"emitterChainId","type":"uint16"},{"internalType":"bytes32","name":"emitterAddress","type":"bytes32"},{"internalType":"uint64","name":"sequence","type":"uint64"},{"internalType":"uint8","name":"consistencyLevel","type":"uint8"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"uint32","name":"guardianSetIndex","type":"uint32"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"uint8","name":"guardianIndex","type":"uint8"}],"internalType":"struct Structs.Signature[]","name":"signatures","type":"tuple[]"},{"internalType":"bytes32","name":"hash","type":"bytes32"}],"internalType":"struct Structs.VM","name":"vm","type":"tuple"}],"name":"verifyVM","outputs":[{"internalType":"bool","name":"valid","type":"bool"},{"internalType":"string","name":"reason","type":"string"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
608060405234801561001057600080fd5b50612fca806100206000396000f3fe60806040526004361061016a5760003560e01c806393df337e116100d1578063c0fd8bde1161008a578063f42bc64111610064578063f42bc64114610612578063f8ce560a14610632578063f951975a14610652578063fbe3c2cd1461067f576101d1565b8063c0fd8bde14610587578063d60b347f146105b6578063eb8d3f12146105ef576101d1565b806393df337e146104ca5780639a8a0592146104ea578063a0cce1b314610512578063a9e1189314610532578063b172b2221461055f578063b19a437e14610574576101d1565b80634fdc60fa116101235780634fdc60fa14610388578063515f3247146103eb5780635cb8cae2146104455780636606b4e0146104675780638129fc1c14610487578063875be02a1461049c576101d1565b80630319e59c1461020757806304ca84cf146102795780631a90a219146102a65780631cfe7951146102c55780632c3c02a4146102f15780634cf842b514610331576101d1565b366101d15760405162461bcd60e51b815260206004820152602c60248201527f74686520576f726d686f6c6520636f6e747261637420646f6573206e6f74206160448201526b63636570742061737365747360a01b60648201526084015b60405180910390fd5b60405162461bcd60e51b815260206004820152600b60248201526a1d5b9cdd5c1c1bdc9d195960aa1b60448201526064016101c8565b34801561021357600080fd5b5061022761022236600461284a565b61069e565b6040516102709190600060a0820190508251825260ff602084015116602083015261ffff6040840151166040830152606083015160608301526080830151608083015292915050565b60405180910390f35b34801561028557600080fd5b5061029961029436600461284a565b6107f4565b6040516102709190612c40565b3480156102b257600080fd5b506007545b604051908152602001610270565b3480156102d157600080fd5b5060035463ffffffff165b60405163ffffffff9091168152602001610270565b3480156102fd57600080fd5b5061032161030c3660046126bf565b60009081526005602052604090205460ff1690565b6040519015158152602001610270565b34801561033d57600080fd5b5061037061034c36600461269e565b6001600160a01b03166000908152600460205260409020546001600160401b031690565b6040516001600160401b039091168152602001610270565b34801561039457600080fd5b506103a86103a336600461284a565b610a27565b60405161027091908151815260208083015160ff169082015260408083015161ffff16908201526060918201516001600160a01b03169181019190915260800190565b3480156103f757600080fd5b5061040b61040636600461284a565b610b63565b60405161027091908151815260208083015160ff169082015260408083015161ffff16908201526060918201519181019190915260800190565b34801561045157600080fd5b5061046561046036600461284a565b610c92565b005b34801561047357600080fd5b5061046561048236600461284a565b610d9a565b34801561049357600080fd5b50610465610fba565b3480156104a857600080fd5b506104bc6104b7366004612884565b61107f565b604051610270929190612c12565b3480156104d657600080fd5b506104656104e536600461284a565b6111e2565b3480156104f657600080fd5b5060005461ffff165b60405161ffff9091168152602001610270565b34801561051e57600080fd5b506104bc61052d3660046126d7565b61132e565b34801561053e57600080fd5b5061055261054d36600461284a565b61150b565b6040516102709190612cb0565b34801561056b57600080fd5b506001546102b7565b6103706105823660046129bd565b6118e9565b34801561059357600080fd5b506105a76105a23660046127de565b611989565b60405161027093929190612cc3565b3480156105c257600080fd5b506103216105d136600461269e565b6001600160a01b031660009081526006602052604090205460ff1690565b3480156105fb57600080fd5b50600354640100000000900463ffffffff166102dc565b34801561061e57600080fd5b5061046561062d36600461284a565b6119eb565b34801561063e57600080fd5b506102b761064d3660046126bf565b611aec565b34801561065e57600080fd5b5061067261066d3660046129a3565b611b16565b6040516102709190612c9d565b34801561068b57600080fd5b5060005462010000900461ffff166104ff565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101829052906106d38382611bb5565b82526106e0602082612dfc565b90506106ec8382611c13565b60ff1660208301526106ff600182612dfc565b9050816020015160ff1660041461074f5760405162461bcd60e51b8152602060048201526014602482015273696e76616c6964205472616e736665724665657360601b60448201526064016101c8565b6107598382611c6f565b61ffff16604083015261076d600282612dfc565b90506107798382611ccc565b6060830152610789602082612dfc565b90506107958382611bb5565b60808301526107a5602082612dfc565b9050808351146107ee5760405162461bcd60e51b8152602060048201526014602482015273696e76616c6964205472616e736665724665657360601b60448201526064016101c8565b50919050565b6107fc6123ec565b60006108088382611bb5565b8252610815602082612dfc565b90506108218382611c13565b60ff166020830152610834600182612dfc565b9050816020015160ff1660021461088d5760405162461bcd60e51b815260206004820152601a60248201527f696e76616c696420477561726469616e5365745570677261646500000000000060448201526064016101c8565b6108978382611c6f565b61ffff1660408301526108ab600282612dfc565b90506108b78382611d21565b63ffffffff1660808301526108cd600482612dfc565b905060006108db8483611c13565b90506108e8600183612dfc565b915060405180604001604052808260ff166001600160401b0381111561091e57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610947578160200160208202803683370190505b5081526000602090910181905260608501919091525b8160ff168110156109cf576109728584611d7e565b60608501515180518390811061099857634e487b7160e01b600052603260045260246000fd5b6001600160a01b03909216602092830291909101909101526109bb601484612dfc565b9250806109c781612f09565b91505061095d565b5081845114610a205760405162461bcd60e51b815260206004820152601a60248201527f696e76616c696420477561726469616e5365745570677261646500000000000060448201526064016101c8565b5050919050565b604080516080810182526000808252602082018190529181018290526060810182905290610a558382611bb5565b8252610a62602082612dfc565b9050610a6e8382611c13565b60ff166020830152610a81600182612dfc565b9050816020015160ff16600114610ad45760405162461bcd60e51b8152602060048201526017602482015276696e76616c696420436f6e74726163745570677261646560481b60448201526064016101c8565b610ade8382611c6f565b61ffff166040830152610af2600282612dfc565b9050610afe8382611bb5565b6001600160a01b03166060830152610b17602082612dfc565b9050808351146107ee5760405162461bcd60e51b8152602060048201526017602482015276696e76616c696420436f6e74726163745570677261646560481b60448201526064016101c8565b604080516080810182526000808252602082018190529181018290526060810182905290610b918382611bb5565b8252610b9e602082612dfc565b9050610baa8382611c13565b60ff166020830152610bbd600182612dfc565b9050816020015160ff16600314610c0e5760405162461bcd60e51b8152602060048201526015602482015274696e76616c6964205365744d65737361676546656560581b60448201526064016101c8565b610c188382611c6f565b61ffff166040830152610c2c600282612dfc565b9050610c388382611ccc565b6060830152610c48602082612dfc565b9050808351146107ee5760405162461bcd60e51b8152602060048201526015602482015274696e76616c6964205365744d65737361676546656560581b60448201526064016101c8565b6000610c9d8261150b565b9050600080610cab83611de3565b91509150818190610ccf5760405162461bcd60e51b81526004016101c89190612c2d565b506000610cdf8460e00151610a27565b805190915063436f726514610d275760405162461bcd60e51b815260206004820152600e60248201526d496e76616c6964204d6f64756c6560901b60448201526064016101c8565b60005461ffff1661ffff16816040015161ffff1614610d785760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b21021b430b4b760991b60448201526064016101c8565b610d86846101400151611f59565b610d938160600151611f74565b5050505050565b6000610da58261150b565b9050600080610db383611de3565b91509150818190610dd75760405162461bcd60e51b81526004016101c89190612c2d565b506000610de78460e001516107f4565b805190915063436f726514610e2f5760405162461bcd60e51b815260206004820152600e60248201526d696e76616c6964204d6f64756c6560901b60448201526064016101c8565b60005461ffff1661ffff16816040015161ffff161480610e555750604081015161ffff16155b610e915760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b21021b430b4b760991b60448201526064016101c8565b60608101515151610ee45760405162461bcd60e51b815260206004820152601960248201527f6e657720677561726469616e2073657420697320656d7074790000000000000060448201526064016101c8565b60035463ffffffff16610ef8906001612e14565b63ffffffff16816080015163ffffffff1614610f605760405162461bcd60e51b815260206004820152602160248201527f696e646578206d75737420696e63726561736520696e207374657073206f66206044820152603160f81b60648201526084016101c8565b610f6e846101400151611f59565b610f85610f8060035463ffffffff1690565b6120a1565b610f97816060015182608001516120d9565b60808101516003805463ffffffff191663ffffffff909216919091179055610d93565b6000610fed7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b9050611011816001600160a01b031660009081526006602052604090205460ff1690565b156110545760405162461bcd60e51b8152602060048201526013602482015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b60448201526064016101c8565b61107c816001600160a01b03166000908152600660205260409020805460ff19166001179055565b50565b600060606000611093846101000151611b16565b8051519091506110d6576000604051806040016040528060148152602001731a5b9d985b1a590819dd585c991a585b881cd95d60621b8152509250925050915091565b60035463ffffffff1663ffffffff1684610100015163ffffffff1614158015611108575042816020015163ffffffff16105b1561114f5760006040518060400160405280601881526020017f677561726469616e2073657420686173206578706972656400000000000000008152509250925050915091565b80515161115b90611aec565b846101200151511015611196576000604051806040016040528060098152602001686e6f2071756f72756d60b81b8152509250925050915091565b6000806111ae8661014001518761012001518561132e565b91509150816111c4576000969095509350505050565b60016040518060200160405280600081525094509450505050915091565b60006111ed8261150b565b90506000806111fb83611de3565b9150915081819061121f5760405162461bcd60e51b81526004016101c89190612c2d565b50600061122f8460e0015161069e565b805190915063436f7265146112775760405162461bcd60e51b815260206004820152600e60248201526d696e76616c6964204d6f64756c6560901b60448201526064016101c8565b60005461ffff1661ffff16816040015161ffff16148061129d5750604081015161ffff16155b6112d95760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b21021b430b4b760991b60448201526064016101c8565b6112e7846101400151611f59565b608081015160608201516040516001600160a01b0383169180156108fc02916000818181858888f19350505050158015611325573d6000803e3d6000fd5b50505050505050565b600060606000805b85518110156114ea57600086828151811061136157634e487b7160e01b600052603260045260246000fd5b60200260200101519050816000148061138357508260ff16816060015160ff16115b6113db5760405162461bcd60e51b815260206004820152602360248201527f7369676e617475726520696e6469636573206d75737420626520617363656e64604482015262696e6760e81b60648201526084016101c8565b6060810151865180519194509060ff851690811061140957634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b031660018983604001518460000151856020015160405160008152602001604052604051611462949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611484573d6000803e3d6000fd5b505050602060405103516001600160a01b0316146114d7576000604051806040016040528060148152602001731593481cda59db985d1d5c99481a5b9d985b1a5960621b81525094509450505050611503565b50806114e281612f09565b915050611336565b5060016040518060200160405280600081525092509250505b935093915050565b611513612446565b600061151f8382611c13565b60ff16825261152f600182612dfc565b9050816000015160ff166001146115885760405162461bcd60e51b815260206004820152601760248201527f564d2076657273696f6e20696e636f6d70617469626c6500000000000000000060448201526064016101c8565b6115928382611d21565b63ffffffff166101008301526115a9600482612dfc565b905060006115b78483611c13565b60ff1690506115c7600183612dfc565b9150806001600160401b038111156115ef57634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561164157816020015b60408051608081018252600080825260208083018290529282018190526060820152825260001990920191018161160d5790505b5061012084015260005b818110156117b05761165d8584611c13565b846101200151828151811061168257634e487b7160e01b600052603260045260246000fd5b602090810291909101015160ff9091166060909101526116a3600184612dfc565b92506116af8584611bb5565b84610120015182815181106116d457634e487b7160e01b600052603260045260246000fd5b602002602001015160000181815250506020836116f19190612dfc565b92506116fd8584611bb5565b846101200151828151811061172257634e487b7160e01b600052603260045260246000fd5b6020026020010151602001818152505060208361173f9190612dfc565b925061174b8584611c13565b61175690601b612e5e565b846101200151828151811061177b57634e487b7160e01b600052603260045260246000fd5b602090810291909101015160ff90911660409091015261179c600184612dfc565b9250806117a881612f09565b91505061164b565b5060006117cc838487516117c49190612ec2565b87919061212d565b905080805190602001206040516020016117e891815260200190565b60408051601f1981840301815291905280516020909101206101408501526118108584611d21565b63ffffffff166020850152611826600484612dfc565b92506118328584611d21565b63ffffffff166040850152611848600484612dfc565b92506118548584611c6f565b61ffff166060850152611868600284612dfc565b92506118748584611bb5565b6080850152611884602084612dfc565b9250611890858461223a565b6001600160401b031660a08501526118a9600884612dfc565b92506118b58584611c13565b60ff1660c08501526118c8600184612dfc565b92506118db838487516117c49190612ec2565b60e085015250919392505050565b60006118f460075490565b34146119305760405162461bcd60e51b815260206004820152600b60248201526a696e76616c69642066656560a81b60448201526064016101c8565b61193933612297565b9050336001600160a01b03167f6eb224fb001ed210e379b335e35efe88672a8ce935d981a6896b27ffdf52a3b28286868660405161197a9493929190612cfa565b60405180910390a29392505050565b611991612446565b600060606119d485858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061150b92505050565b92506119df8361107f565b93969095509293505050565b60006119f68261150b565b9050600080611a0483611de3565b91509150818190611a285760405162461bcd60e51b81526004016101c89190612c2d565b506000611a388460e00151610b63565b805190915063436f726514611a805760405162461bcd60e51b815260206004820152600e60248201526d496e76616c6964204d6f64756c6560901b60448201526064016101c8565b60005461ffff1661ffff16816040015161ffff1614611ad15760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b21021b430b4b760991b60448201526064016101c8565b611adf846101400151611f59565b610d938160600151600755565b60006003611afb836002612ea3565b611b059190612e83565b611b10906001612dfc565b92915050565b60408051808201825260608082526000602080840182905263ffffffff86168252600281529084902084518154928302810184018652948501828152939493909284928491840182828015611b9457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611b76575b50505091835250506001919091015463ffffffff1660209091015292915050565b6000611bc2826020612dfc565b83511015611c0a5760405162461bcd60e51b8152602060048201526015602482015274746f427974657333325f6f75744f66426f756e647360581b60448201526064016101c8565b50016020015190565b6000611c20826001612dfc565b83511015611c665760405162461bcd60e51b8152602060048201526013602482015272746f55696e74385f6f75744f66426f756e647360681b60448201526064016101c8565b50016001015190565b6000611c7c826002612dfc565b83511015611cc35760405162461bcd60e51b8152602060048201526014602482015273746f55696e7431365f6f75744f66426f756e647360601b60448201526064016101c8565b50016002015190565b6000611cd9826020612dfc565b83511015611c0a5760405162461bcd60e51b8152602060048201526015602482015274746f55696e743235365f6f75744f66426f756e647360581b60448201526064016101c8565b6000611d2e826004612dfc565b83511015611d755760405162461bcd60e51b8152602060048201526014602482015273746f55696e7433325f6f75744f66426f756e647360601b60448201526064016101c8565b50016004015190565b6000611d8b826014612dfc565b83511015611dd35760405162461bcd60e51b8152602060048201526015602482015274746f416464726573735f6f75744f66426f756e647360581b60448201526064016101c8565b500160200151600160601b900490565b60006060600080611df38561107f565b9150915081611e085760009590945092505050565b60035463ffffffff1663ffffffff1685610100015163ffffffff1614611e4e576000604051806060016040528060228152602001612f5160229139935093505050915091565b60005462010000900461ffff1661ffff16856060015161ffff1614611ea9576000604051806040016040528060168152602001753bb937b7339033b7bb32b93730b731b29031b430b4b760511b815250935093505050915091565b600154856080015114611ef95760006040518060400160405280601981526020017f77726f6e6720676f7665726e616e636520636f6e747261637400000000000000815250935093505050915091565b61014085015160009081526005602052604090205460ff1615611f3c576000604051806060016040528060228152602001612f7360229139935093505050915091565b600160405180602001604052806000815250935093505050915091565b6000908152600560205260409020805460ff19166001179055565b6000611fa77f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b9050611fb282612307565b60408051600481526024810182526020810180516001600160e01b031663204a7f0760e21b179052905160009182916001600160a01b03861691611ff591612bf6565b600060405180830381855af49150503d8060008114612030576040519150601f19603f3d011682016040523d82523d6000602084013e612035565b606091505b509150915081819061205a5760405162461bcd60e51b81526004016101c89190612c2d565b50836001600160a01b0316836001600160a01b03167f2e4cc16c100f0b55e2df82ab0b1a7e294aa9cbd01b48fbaf622683fbc0507a4960405160405180910390a350505050565b6120ae4262015180612e14565b63ffffffff9182166000908152600260205260409020600101805463ffffffff191691909216179055565b63ffffffff811660009081526002602090815260409091208351805185936121059284929101906124a1565b50602091909101516001909101805463ffffffff191663ffffffff9092169190911790555050565b60608161213b81601f612dfc565b101561217a5760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b60448201526064016101c8565b6121848284612dfc565b845110156121c85760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b60448201526064016101c8565b6060821580156121e75760405191506000825260208201604052612231565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015612220578051835260209283019201612208565b5050858452601f01601f1916604052505b50949350505050565b6000612247826008612dfc565b8351101561228e5760405162461bcd60e51b8152602060048201526014602482015273746f55696e7436345f6f75744f66426f756e647360601b60448201526064016101c8565b50016008015190565b6001600160a01b0381166000908152600460205260409020546001600160401b0316612302826122c8836001612e3c565b6001600160a01b03919091166000908152600460205260409020805467ffffffffffffffff19166001600160401b03909216919091179055565b919050565b61231081612347565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b803b6123ab5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016101c8565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0392909216919091179055565b6040518060a0016040528060008019168152602001600060ff168152602001600061ffff168152602001612439604051806040016040528060608152602001600063ffffffff1681525090565b8152600060209091015290565b604080516101608101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e08201819052610100820183905261012082015261014081019190915290565b8280548282559060005260206000209081019282156124f6579160200282015b828111156124f657825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906124c1565b50612502929150612506565b5090565b5b808211156125025760008155600101612507565b80356001600160a01b038116811461230257600080fd5b600082601f830112612542578081fd5b8135602061255761255283612dd9565b612da9565b80838252828201915082860187848660071b8901011115612576578586fd5b855b858110156125d957608080838b031215612590578788fd5b612598612d3c565b83358152868401358782015260406125b181860161268d565b9082015260606125c285820161268d565b908201528552938501939190910190600101612578565b5090979650505050505050565b600082601f8301126125f6578081fd5b81356001600160401b0381111561260f5761260f612f3a565b612622601f8201601f1916602001612da9565b818152846020838601011115612636578283fd5b816020850160208301379081016020019190915292915050565b803561ffff8116811461230257600080fd5b803563ffffffff8116811461230257600080fd5b80356001600160401b038116811461230257600080fd5b803560ff8116811461230257600080fd5b6000602082840312156126af578081fd5b6126b88261251b565b9392505050565b6000602082840312156126d0578081fd5b5035919050565b6000806000606084860312156126eb578182fd5b833592506020808501356001600160401b0380821115612709578485fd5b61271588838901612532565b9450604087013591508082111561272a578384fd5b908601906040828903121561273d578384fd5b612745612d64565b823582811115612753578586fd5b83019150601f82018913612765578485fd5b813561277361255282612dd9565b8082825286820191508685018c888560051b8801011115612792578889fd5b8895505b838610156127bb576127a78161251b565b835260019590950194918701918701612796565b508352506127cc9050838501612662565b84820152809450505050509250925092565b600080602083850312156127f0578182fd5b82356001600160401b0380821115612806578384fd5b818501915085601f830112612819578384fd5b813581811115612827578485fd5b866020828501011115612838578485fd5b60209290920196919550909350505050565b60006020828403121561285b578081fd5b81356001600160401b03811115612870578182fd5b61287c848285016125e6565b949350505050565b600060208284031215612895578081fd5b81356001600160401b03808211156128ab578283fd5b9083019061016082860312156128bf578283fd5b6128c7612d86565b6128d08361268d565b81526128de60208401612662565b60208201526128ef60408401612662565b604082015261290060608401612650565b60608201526080830135608082015261291b60a08401612676565b60a082015261292c60c0840161268d565b60c082015260e083013582811115612942578485fd5b61294e878286016125e6565b60e083015250610100612962818501612662565b908201526101208381013583811115612979578586fd5b61298588828701612532565b91830191909152506101409283013592810192909252509392505050565b6000602082840312156129b4578081fd5b6126b882612662565b6000806000606084860312156129d1578081fd5b6129da84612662565b925060208401356001600160401b038111156129f4578182fd5b612a00868287016125e6565b925050612a0f6040850161268d565b90509250925092565b6000815180845260208085019450808401835b83811015612a7057815180518852838101518489015260408082015160ff908116918a0191909152606091820151169088015260809096019590820190600101612a2b565b509495945050505050565b60008151808452612a93816020860160208601612ed9565b601f01601f19169290920160200192915050565b805160408084528151908401819052600091602091908201906060860190845b81811015612aec5783516001600160a01b031683529284019291840191600101612ac7565b50509382015163ffffffff16949091019390935250919050565b805160ff16825260006101606020830151612b29602086018263ffffffff169052565b506040830151612b41604086018263ffffffff169052565b506060830151612b57606086018261ffff169052565b506080830151608085015260a0830151612b7c60a08601826001600160401b03169052565b5060c0830151612b9160c086018260ff169052565b5060e08301518160e0860152612ba982860182612a7b565b91505061010080840151612bc48287018263ffffffff169052565b50506101208084015185830382870152612bde8382612a18565b61014095860151969095019590955250919392505050565b60008251612c08818460208701612ed9565b9190910192915050565b821515815260406020820152600061287c6040830184612a7b565b6020815260006126b86020830184612a7b565b602081528151602082015260ff602083015116604082015261ffff60408301511660608201526000606083015160a06080840152612c8160c0840182612aa7565b905063ffffffff60808501511660a08401528091505092915050565b6020815260006126b86020830184612aa7565b6020815260006126b86020830184612b06565b606081526000612cd66060830186612b06565b84151560208401528281036040840152612cf08185612a7b565b9695505050505050565b6001600160401b038516815263ffffffff84166020820152608060408201526000612d286080830185612a7b565b905060ff8316606083015295945050505050565b604051608081016001600160401b0381118282101715612d5e57612d5e612f3a565b60405290565b604080519081016001600160401b0381118282101715612d5e57612d5e612f3a565b60405161016081016001600160401b0381118282101715612d5e57612d5e612f3a565b604051601f8201601f191681016001600160401b0381118282101715612dd157612dd1612f3a565b604052919050565b60006001600160401b03821115612df257612df2612f3a565b5060051b60200190565b60008219821115612e0f57612e0f612f24565b500190565b600063ffffffff808316818516808303821115612e3357612e33612f24565b01949350505050565b60006001600160401b03808316818516808303821115612e3357612e33612f24565b600060ff821660ff84168060ff03821115612e7b57612e7b612f24565b019392505050565b600082612e9e57634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615612ebd57612ebd612f24565b500290565b600082821015612ed457612ed4612f24565b500390565b60005b83811015612ef4578181015183820152602001612edc565b83811115612f03576000848401525b50505050565b6000600019821415612f1d57612f1d612f24565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fdfe6e6f74207369676e65642062792063757272656e7420677561726469616e20736574676f7665726e616e636520616374696f6e20616c726561647920636f6e73756d6564a2646970667358221220a776ad2c46edd3dd8c68f70e60090b7c22541409e7834950fb9854143876906864736f6c63430008040033
Deployed Bytecode
0x60806040526004361061016a5760003560e01c806393df337e116100d1578063c0fd8bde1161008a578063f42bc64111610064578063f42bc64114610612578063f8ce560a14610632578063f951975a14610652578063fbe3c2cd1461067f576101d1565b8063c0fd8bde14610587578063d60b347f146105b6578063eb8d3f12146105ef576101d1565b806393df337e146104ca5780639a8a0592146104ea578063a0cce1b314610512578063a9e1189314610532578063b172b2221461055f578063b19a437e14610574576101d1565b80634fdc60fa116101235780634fdc60fa14610388578063515f3247146103eb5780635cb8cae2146104455780636606b4e0146104675780638129fc1c14610487578063875be02a1461049c576101d1565b80630319e59c1461020757806304ca84cf146102795780631a90a219146102a65780631cfe7951146102c55780632c3c02a4146102f15780634cf842b514610331576101d1565b366101d15760405162461bcd60e51b815260206004820152602c60248201527f74686520576f726d686f6c6520636f6e747261637420646f6573206e6f74206160448201526b63636570742061737365747360a01b60648201526084015b60405180910390fd5b60405162461bcd60e51b815260206004820152600b60248201526a1d5b9cdd5c1c1bdc9d195960aa1b60448201526064016101c8565b34801561021357600080fd5b5061022761022236600461284a565b61069e565b6040516102709190600060a0820190508251825260ff602084015116602083015261ffff6040840151166040830152606083015160608301526080830151608083015292915050565b60405180910390f35b34801561028557600080fd5b5061029961029436600461284a565b6107f4565b6040516102709190612c40565b3480156102b257600080fd5b506007545b604051908152602001610270565b3480156102d157600080fd5b5060035463ffffffff165b60405163ffffffff9091168152602001610270565b3480156102fd57600080fd5b5061032161030c3660046126bf565b60009081526005602052604090205460ff1690565b6040519015158152602001610270565b34801561033d57600080fd5b5061037061034c36600461269e565b6001600160a01b03166000908152600460205260409020546001600160401b031690565b6040516001600160401b039091168152602001610270565b34801561039457600080fd5b506103a86103a336600461284a565b610a27565b60405161027091908151815260208083015160ff169082015260408083015161ffff16908201526060918201516001600160a01b03169181019190915260800190565b3480156103f757600080fd5b5061040b61040636600461284a565b610b63565b60405161027091908151815260208083015160ff169082015260408083015161ffff16908201526060918201519181019190915260800190565b34801561045157600080fd5b5061046561046036600461284a565b610c92565b005b34801561047357600080fd5b5061046561048236600461284a565b610d9a565b34801561049357600080fd5b50610465610fba565b3480156104a857600080fd5b506104bc6104b7366004612884565b61107f565b604051610270929190612c12565b3480156104d657600080fd5b506104656104e536600461284a565b6111e2565b3480156104f657600080fd5b5060005461ffff165b60405161ffff9091168152602001610270565b34801561051e57600080fd5b506104bc61052d3660046126d7565b61132e565b34801561053e57600080fd5b5061055261054d36600461284a565b61150b565b6040516102709190612cb0565b34801561056b57600080fd5b506001546102b7565b6103706105823660046129bd565b6118e9565b34801561059357600080fd5b506105a76105a23660046127de565b611989565b60405161027093929190612cc3565b3480156105c257600080fd5b506103216105d136600461269e565b6001600160a01b031660009081526006602052604090205460ff1690565b3480156105fb57600080fd5b50600354640100000000900463ffffffff166102dc565b34801561061e57600080fd5b5061046561062d36600461284a565b6119eb565b34801561063e57600080fd5b506102b761064d3660046126bf565b611aec565b34801561065e57600080fd5b5061067261066d3660046129a3565b611b16565b6040516102709190612c9d565b34801561068b57600080fd5b5060005462010000900461ffff166104ff565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101829052906106d38382611bb5565b82526106e0602082612dfc565b90506106ec8382611c13565b60ff1660208301526106ff600182612dfc565b9050816020015160ff1660041461074f5760405162461bcd60e51b8152602060048201526014602482015273696e76616c6964205472616e736665724665657360601b60448201526064016101c8565b6107598382611c6f565b61ffff16604083015261076d600282612dfc565b90506107798382611ccc565b6060830152610789602082612dfc565b90506107958382611bb5565b60808301526107a5602082612dfc565b9050808351146107ee5760405162461bcd60e51b8152602060048201526014602482015273696e76616c6964205472616e736665724665657360601b60448201526064016101c8565b50919050565b6107fc6123ec565b60006108088382611bb5565b8252610815602082612dfc565b90506108218382611c13565b60ff166020830152610834600182612dfc565b9050816020015160ff1660021461088d5760405162461bcd60e51b815260206004820152601a60248201527f696e76616c696420477561726469616e5365745570677261646500000000000060448201526064016101c8565b6108978382611c6f565b61ffff1660408301526108ab600282612dfc565b90506108b78382611d21565b63ffffffff1660808301526108cd600482612dfc565b905060006108db8483611c13565b90506108e8600183612dfc565b915060405180604001604052808260ff166001600160401b0381111561091e57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610947578160200160208202803683370190505b5081526000602090910181905260608501919091525b8160ff168110156109cf576109728584611d7e565b60608501515180518390811061099857634e487b7160e01b600052603260045260246000fd5b6001600160a01b03909216602092830291909101909101526109bb601484612dfc565b9250806109c781612f09565b91505061095d565b5081845114610a205760405162461bcd60e51b815260206004820152601a60248201527f696e76616c696420477561726469616e5365745570677261646500000000000060448201526064016101c8565b5050919050565b604080516080810182526000808252602082018190529181018290526060810182905290610a558382611bb5565b8252610a62602082612dfc565b9050610a6e8382611c13565b60ff166020830152610a81600182612dfc565b9050816020015160ff16600114610ad45760405162461bcd60e51b8152602060048201526017602482015276696e76616c696420436f6e74726163745570677261646560481b60448201526064016101c8565b610ade8382611c6f565b61ffff166040830152610af2600282612dfc565b9050610afe8382611bb5565b6001600160a01b03166060830152610b17602082612dfc565b9050808351146107ee5760405162461bcd60e51b8152602060048201526017602482015276696e76616c696420436f6e74726163745570677261646560481b60448201526064016101c8565b604080516080810182526000808252602082018190529181018290526060810182905290610b918382611bb5565b8252610b9e602082612dfc565b9050610baa8382611c13565b60ff166020830152610bbd600182612dfc565b9050816020015160ff16600314610c0e5760405162461bcd60e51b8152602060048201526015602482015274696e76616c6964205365744d65737361676546656560581b60448201526064016101c8565b610c188382611c6f565b61ffff166040830152610c2c600282612dfc565b9050610c388382611ccc565b6060830152610c48602082612dfc565b9050808351146107ee5760405162461bcd60e51b8152602060048201526015602482015274696e76616c6964205365744d65737361676546656560581b60448201526064016101c8565b6000610c9d8261150b565b9050600080610cab83611de3565b91509150818190610ccf5760405162461bcd60e51b81526004016101c89190612c2d565b506000610cdf8460e00151610a27565b805190915063436f726514610d275760405162461bcd60e51b815260206004820152600e60248201526d496e76616c6964204d6f64756c6560901b60448201526064016101c8565b60005461ffff1661ffff16816040015161ffff1614610d785760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b21021b430b4b760991b60448201526064016101c8565b610d86846101400151611f59565b610d938160600151611f74565b5050505050565b6000610da58261150b565b9050600080610db383611de3565b91509150818190610dd75760405162461bcd60e51b81526004016101c89190612c2d565b506000610de78460e001516107f4565b805190915063436f726514610e2f5760405162461bcd60e51b815260206004820152600e60248201526d696e76616c6964204d6f64756c6560901b60448201526064016101c8565b60005461ffff1661ffff16816040015161ffff161480610e555750604081015161ffff16155b610e915760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b21021b430b4b760991b60448201526064016101c8565b60608101515151610ee45760405162461bcd60e51b815260206004820152601960248201527f6e657720677561726469616e2073657420697320656d7074790000000000000060448201526064016101c8565b60035463ffffffff16610ef8906001612e14565b63ffffffff16816080015163ffffffff1614610f605760405162461bcd60e51b815260206004820152602160248201527f696e646578206d75737420696e63726561736520696e207374657073206f66206044820152603160f81b60648201526084016101c8565b610f6e846101400151611f59565b610f85610f8060035463ffffffff1690565b6120a1565b610f97816060015182608001516120d9565b60808101516003805463ffffffff191663ffffffff909216919091179055610d93565b6000610fed7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b9050611011816001600160a01b031660009081526006602052604090205460ff1690565b156110545760405162461bcd60e51b8152602060048201526013602482015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b60448201526064016101c8565b61107c816001600160a01b03166000908152600660205260409020805460ff19166001179055565b50565b600060606000611093846101000151611b16565b8051519091506110d6576000604051806040016040528060148152602001731a5b9d985b1a590819dd585c991a585b881cd95d60621b8152509250925050915091565b60035463ffffffff1663ffffffff1684610100015163ffffffff1614158015611108575042816020015163ffffffff16105b1561114f5760006040518060400160405280601881526020017f677561726469616e2073657420686173206578706972656400000000000000008152509250925050915091565b80515161115b90611aec565b846101200151511015611196576000604051806040016040528060098152602001686e6f2071756f72756d60b81b8152509250925050915091565b6000806111ae8661014001518761012001518561132e565b91509150816111c4576000969095509350505050565b60016040518060200160405280600081525094509450505050915091565b60006111ed8261150b565b90506000806111fb83611de3565b9150915081819061121f5760405162461bcd60e51b81526004016101c89190612c2d565b50600061122f8460e0015161069e565b805190915063436f7265146112775760405162461bcd60e51b815260206004820152600e60248201526d696e76616c6964204d6f64756c6560901b60448201526064016101c8565b60005461ffff1661ffff16816040015161ffff16148061129d5750604081015161ffff16155b6112d95760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b21021b430b4b760991b60448201526064016101c8565b6112e7846101400151611f59565b608081015160608201516040516001600160a01b0383169180156108fc02916000818181858888f19350505050158015611325573d6000803e3d6000fd5b50505050505050565b600060606000805b85518110156114ea57600086828151811061136157634e487b7160e01b600052603260045260246000fd5b60200260200101519050816000148061138357508260ff16816060015160ff16115b6113db5760405162461bcd60e51b815260206004820152602360248201527f7369676e617475726520696e6469636573206d75737420626520617363656e64604482015262696e6760e81b60648201526084016101c8565b6060810151865180519194509060ff851690811061140957634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b031660018983604001518460000151856020015160405160008152602001604052604051611462949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611484573d6000803e3d6000fd5b505050602060405103516001600160a01b0316146114d7576000604051806040016040528060148152602001731593481cda59db985d1d5c99481a5b9d985b1a5960621b81525094509450505050611503565b50806114e281612f09565b915050611336565b5060016040518060200160405280600081525092509250505b935093915050565b611513612446565b600061151f8382611c13565b60ff16825261152f600182612dfc565b9050816000015160ff166001146115885760405162461bcd60e51b815260206004820152601760248201527f564d2076657273696f6e20696e636f6d70617469626c6500000000000000000060448201526064016101c8565b6115928382611d21565b63ffffffff166101008301526115a9600482612dfc565b905060006115b78483611c13565b60ff1690506115c7600183612dfc565b9150806001600160401b038111156115ef57634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561164157816020015b60408051608081018252600080825260208083018290529282018190526060820152825260001990920191018161160d5790505b5061012084015260005b818110156117b05761165d8584611c13565b846101200151828151811061168257634e487b7160e01b600052603260045260246000fd5b602090810291909101015160ff9091166060909101526116a3600184612dfc565b92506116af8584611bb5565b84610120015182815181106116d457634e487b7160e01b600052603260045260246000fd5b602002602001015160000181815250506020836116f19190612dfc565b92506116fd8584611bb5565b846101200151828151811061172257634e487b7160e01b600052603260045260246000fd5b6020026020010151602001818152505060208361173f9190612dfc565b925061174b8584611c13565b61175690601b612e5e565b846101200151828151811061177b57634e487b7160e01b600052603260045260246000fd5b602090810291909101015160ff90911660409091015261179c600184612dfc565b9250806117a881612f09565b91505061164b565b5060006117cc838487516117c49190612ec2565b87919061212d565b905080805190602001206040516020016117e891815260200190565b60408051601f1981840301815291905280516020909101206101408501526118108584611d21565b63ffffffff166020850152611826600484612dfc565b92506118328584611d21565b63ffffffff166040850152611848600484612dfc565b92506118548584611c6f565b61ffff166060850152611868600284612dfc565b92506118748584611bb5565b6080850152611884602084612dfc565b9250611890858461223a565b6001600160401b031660a08501526118a9600884612dfc565b92506118b58584611c13565b60ff1660c08501526118c8600184612dfc565b92506118db838487516117c49190612ec2565b60e085015250919392505050565b60006118f460075490565b34146119305760405162461bcd60e51b815260206004820152600b60248201526a696e76616c69642066656560a81b60448201526064016101c8565b61193933612297565b9050336001600160a01b03167f6eb224fb001ed210e379b335e35efe88672a8ce935d981a6896b27ffdf52a3b28286868660405161197a9493929190612cfa565b60405180910390a29392505050565b611991612446565b600060606119d485858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061150b92505050565b92506119df8361107f565b93969095509293505050565b60006119f68261150b565b9050600080611a0483611de3565b91509150818190611a285760405162461bcd60e51b81526004016101c89190612c2d565b506000611a388460e00151610b63565b805190915063436f726514611a805760405162461bcd60e51b815260206004820152600e60248201526d496e76616c6964204d6f64756c6560901b60448201526064016101c8565b60005461ffff1661ffff16816040015161ffff1614611ad15760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b21021b430b4b760991b60448201526064016101c8565b611adf846101400151611f59565b610d938160600151600755565b60006003611afb836002612ea3565b611b059190612e83565b611b10906001612dfc565b92915050565b60408051808201825260608082526000602080840182905263ffffffff86168252600281529084902084518154928302810184018652948501828152939493909284928491840182828015611b9457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611b76575b50505091835250506001919091015463ffffffff1660209091015292915050565b6000611bc2826020612dfc565b83511015611c0a5760405162461bcd60e51b8152602060048201526015602482015274746f427974657333325f6f75744f66426f756e647360581b60448201526064016101c8565b50016020015190565b6000611c20826001612dfc565b83511015611c665760405162461bcd60e51b8152602060048201526013602482015272746f55696e74385f6f75744f66426f756e647360681b60448201526064016101c8565b50016001015190565b6000611c7c826002612dfc565b83511015611cc35760405162461bcd60e51b8152602060048201526014602482015273746f55696e7431365f6f75744f66426f756e647360601b60448201526064016101c8565b50016002015190565b6000611cd9826020612dfc565b83511015611c0a5760405162461bcd60e51b8152602060048201526015602482015274746f55696e743235365f6f75744f66426f756e647360581b60448201526064016101c8565b6000611d2e826004612dfc565b83511015611d755760405162461bcd60e51b8152602060048201526014602482015273746f55696e7433325f6f75744f66426f756e647360601b60448201526064016101c8565b50016004015190565b6000611d8b826014612dfc565b83511015611dd35760405162461bcd60e51b8152602060048201526015602482015274746f416464726573735f6f75744f66426f756e647360581b60448201526064016101c8565b500160200151600160601b900490565b60006060600080611df38561107f565b9150915081611e085760009590945092505050565b60035463ffffffff1663ffffffff1685610100015163ffffffff1614611e4e576000604051806060016040528060228152602001612f5160229139935093505050915091565b60005462010000900461ffff1661ffff16856060015161ffff1614611ea9576000604051806040016040528060168152602001753bb937b7339033b7bb32b93730b731b29031b430b4b760511b815250935093505050915091565b600154856080015114611ef95760006040518060400160405280601981526020017f77726f6e6720676f7665726e616e636520636f6e747261637400000000000000815250935093505050915091565b61014085015160009081526005602052604090205460ff1615611f3c576000604051806060016040528060228152602001612f7360229139935093505050915091565b600160405180602001604052806000815250935093505050915091565b6000908152600560205260409020805460ff19166001179055565b6000611fa77f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b9050611fb282612307565b60408051600481526024810182526020810180516001600160e01b031663204a7f0760e21b179052905160009182916001600160a01b03861691611ff591612bf6565b600060405180830381855af49150503d8060008114612030576040519150601f19603f3d011682016040523d82523d6000602084013e612035565b606091505b509150915081819061205a5760405162461bcd60e51b81526004016101c89190612c2d565b50836001600160a01b0316836001600160a01b03167f2e4cc16c100f0b55e2df82ab0b1a7e294aa9cbd01b48fbaf622683fbc0507a4960405160405180910390a350505050565b6120ae4262015180612e14565b63ffffffff9182166000908152600260205260409020600101805463ffffffff191691909216179055565b63ffffffff811660009081526002602090815260409091208351805185936121059284929101906124a1565b50602091909101516001909101805463ffffffff191663ffffffff9092169190911790555050565b60608161213b81601f612dfc565b101561217a5760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b60448201526064016101c8565b6121848284612dfc565b845110156121c85760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b60448201526064016101c8565b6060821580156121e75760405191506000825260208201604052612231565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015612220578051835260209283019201612208565b5050858452601f01601f1916604052505b50949350505050565b6000612247826008612dfc565b8351101561228e5760405162461bcd60e51b8152602060048201526014602482015273746f55696e7436345f6f75744f66426f756e647360601b60448201526064016101c8565b50016008015190565b6001600160a01b0381166000908152600460205260409020546001600160401b0316612302826122c8836001612e3c565b6001600160a01b03919091166000908152600460205260409020805467ffffffffffffffff19166001600160401b03909216919091179055565b919050565b61231081612347565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b803b6123ab5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016101c8565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0392909216919091179055565b6040518060a0016040528060008019168152602001600060ff168152602001600061ffff168152602001612439604051806040016040528060608152602001600063ffffffff1681525090565b8152600060209091015290565b604080516101608101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e08201819052610100820183905261012082015261014081019190915290565b8280548282559060005260206000209081019282156124f6579160200282015b828111156124f657825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906124c1565b50612502929150612506565b5090565b5b808211156125025760008155600101612507565b80356001600160a01b038116811461230257600080fd5b600082601f830112612542578081fd5b8135602061255761255283612dd9565b612da9565b80838252828201915082860187848660071b8901011115612576578586fd5b855b858110156125d957608080838b031215612590578788fd5b612598612d3c565b83358152868401358782015260406125b181860161268d565b9082015260606125c285820161268d565b908201528552938501939190910190600101612578565b5090979650505050505050565b600082601f8301126125f6578081fd5b81356001600160401b0381111561260f5761260f612f3a565b612622601f8201601f1916602001612da9565b818152846020838601011115612636578283fd5b816020850160208301379081016020019190915292915050565b803561ffff8116811461230257600080fd5b803563ffffffff8116811461230257600080fd5b80356001600160401b038116811461230257600080fd5b803560ff8116811461230257600080fd5b6000602082840312156126af578081fd5b6126b88261251b565b9392505050565b6000602082840312156126d0578081fd5b5035919050565b6000806000606084860312156126eb578182fd5b833592506020808501356001600160401b0380821115612709578485fd5b61271588838901612532565b9450604087013591508082111561272a578384fd5b908601906040828903121561273d578384fd5b612745612d64565b823582811115612753578586fd5b83019150601f82018913612765578485fd5b813561277361255282612dd9565b8082825286820191508685018c888560051b8801011115612792578889fd5b8895505b838610156127bb576127a78161251b565b835260019590950194918701918701612796565b508352506127cc9050838501612662565b84820152809450505050509250925092565b600080602083850312156127f0578182fd5b82356001600160401b0380821115612806578384fd5b818501915085601f830112612819578384fd5b813581811115612827578485fd5b866020828501011115612838578485fd5b60209290920196919550909350505050565b60006020828403121561285b578081fd5b81356001600160401b03811115612870578182fd5b61287c848285016125e6565b949350505050565b600060208284031215612895578081fd5b81356001600160401b03808211156128ab578283fd5b9083019061016082860312156128bf578283fd5b6128c7612d86565b6128d08361268d565b81526128de60208401612662565b60208201526128ef60408401612662565b604082015261290060608401612650565b60608201526080830135608082015261291b60a08401612676565b60a082015261292c60c0840161268d565b60c082015260e083013582811115612942578485fd5b61294e878286016125e6565b60e083015250610100612962818501612662565b908201526101208381013583811115612979578586fd5b61298588828701612532565b91830191909152506101409283013592810192909252509392505050565b6000602082840312156129b4578081fd5b6126b882612662565b6000806000606084860312156129d1578081fd5b6129da84612662565b925060208401356001600160401b038111156129f4578182fd5b612a00868287016125e6565b925050612a0f6040850161268d565b90509250925092565b6000815180845260208085019450808401835b83811015612a7057815180518852838101518489015260408082015160ff908116918a0191909152606091820151169088015260809096019590820190600101612a2b565b509495945050505050565b60008151808452612a93816020860160208601612ed9565b601f01601f19169290920160200192915050565b805160408084528151908401819052600091602091908201906060860190845b81811015612aec5783516001600160a01b031683529284019291840191600101612ac7565b50509382015163ffffffff16949091019390935250919050565b805160ff16825260006101606020830151612b29602086018263ffffffff169052565b506040830151612b41604086018263ffffffff169052565b506060830151612b57606086018261ffff169052565b506080830151608085015260a0830151612b7c60a08601826001600160401b03169052565b5060c0830151612b9160c086018260ff169052565b5060e08301518160e0860152612ba982860182612a7b565b91505061010080840151612bc48287018263ffffffff169052565b50506101208084015185830382870152612bde8382612a18565b61014095860151969095019590955250919392505050565b60008251612c08818460208701612ed9565b9190910192915050565b821515815260406020820152600061287c6040830184612a7b565b6020815260006126b86020830184612a7b565b602081528151602082015260ff602083015116604082015261ffff60408301511660608201526000606083015160a06080840152612c8160c0840182612aa7565b905063ffffffff60808501511660a08401528091505092915050565b6020815260006126b86020830184612aa7565b6020815260006126b86020830184612b06565b606081526000612cd66060830186612b06565b84151560208401528281036040840152612cf08185612a7b565b9695505050505050565b6001600160401b038516815263ffffffff84166020820152608060408201526000612d286080830185612a7b565b905060ff8316606083015295945050505050565b604051608081016001600160401b0381118282101715612d5e57612d5e612f3a565b60405290565b604080519081016001600160401b0381118282101715612d5e57612d5e612f3a565b60405161016081016001600160401b0381118282101715612d5e57612d5e612f3a565b604051601f8201601f191681016001600160401b0381118282101715612dd157612dd1612f3a565b604052919050565b60006001600160401b03821115612df257612df2612f3a565b5060051b60200190565b60008219821115612e0f57612e0f612f24565b500190565b600063ffffffff808316818516808303821115612e3357612e33612f24565b01949350505050565b60006001600160401b03808316818516808303821115612e3357612e33612f24565b600060ff821660ff84168060ff03821115612e7b57612e7b612f24565b019392505050565b600082612e9e57634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615612ebd57612ebd612f24565b500290565b600082821015612ed457612ed4612f24565b500390565b60005b83811015612ef4578181015183820152602001612edc565b83811115612f03576000848401525b50505050565b6000600019821415612f1d57612f1d612f24565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fdfe6e6f74207369676e65642062792063757272656e7420677561726469616e20736574676f7665726e616e636520616374696f6e20616c726561647920636f6e73756d6564a2646970667358221220a776ad2c46edd3dd8c68f70e60090b7c22541409e7834950fb9854143876906864736f6c63430008040033
Deployed Bytecode Sourcemap
60416:1395:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61752:54;;-1:-1:-1;;;61752:54:0;;14077:2:1;61752:54:0;;;14059:21:1;14116:2;14096:18;;;14089:30;14155:34;14135:18;;;14128:62;-1:-1:-1;;;14206:18:1;;;14199:42;14258:19;;61752:54:0;;;;;;;;60416:1395;61693:21;;-1:-1:-1;;;61693:21:0;;21958:2:1;61693:21:0;;;21940::1;21997:2;21977:18;;;21970:30;-1:-1:-1;;;22016:18:1;;;22009:41;22067:18;;61693:21:0;21930:161:1;24104:692:0;;;;;;;;;;-1:-1:-1;24104:692:0;;;;;:::i;:::-;;:::i;:::-;;;;;;24512:4:1;24554:3;24543:9;24539:19;24531:27;;24591:6;24585:13;24574:9;24567:32;24667:4;24659;24651:6;24647:17;24641:24;24637:35;24630:4;24619:9;24615:20;24608:65;24741:6;24733:4;24725:6;24721:17;24715:24;24711:37;24704:4;24693:9;24689:20;24682:67;24805:4;24797:6;24793:17;24787:24;24780:4;24769:9;24765:20;24758:54;24868:4;24860:6;24856:17;24850:24;24843:4;24832:9;24828:20;24821:54;24521:360;;;;;24104:692:0;;;;;;;;22302:1019;;;;;;;;;;-1:-1:-1;22302:1019:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;27126:95::-;;;;;;;;;;-1:-1:-1;27196:17:0;;27126:95;;;12508:25:1;;;12496:2;12481:18;27126:95:0;12463:76:1;26241:116:0;;;;;;;;;;-1:-1:-1;26326:23:0;;;;26241:116;;;26166:10:1;26154:23;;;26136:42;;26124:2;26109:18;26241:116:0;26091:93:1;26484:141:0;;;;;;;;;;-1:-1:-1;26484:141:0;;;;;:::i;:::-;26555:4;26579:38;;;:32;:38;;;;;;;;;26484:141;;;;12030:14:1;;12023:22;12005:41;;11993:2;11978:18;26484:141:0;11960:92:1;27229:119:0;;;;;;;;;;-1:-1:-1;27229:119:0;;;;;:::i;:::-;-1:-1:-1;;;;;27315:25:0;27289:6;27315:25;;;:16;:25;;;;;;-1:-1:-1;;;;;27315:25:0;;27229:119;;;;-1:-1:-1;;;;;26351:31:1;;;26333:50;;26321:2;26306:18;27229:119:0;26288:101:1;21597:620:0;;;;;;;;;;-1:-1:-1;21597:620:0;;;;;:::i;:::-;;:::i;:::-;;;;;;22677:13:1;;22659:32;;22751:4;22739:17;;;22733:24;22759:4;22729:35;22707:20;;;22700:65;22825:4;22813:17;;;22807:24;22833:6;22803:37;22781:20;;;22774:67;22901:4;22889:17;;;22883:24;-1:-1:-1;;;;;22879:50:1;22857:20;;;22850:80;;;;22646:3;22631:19;;22613:323;23400:626:0;;;;;;;;;;-1:-1:-1;23400:626:0;;;;;:::i;:::-;;:::i;:::-;;;;;;24124:13:1;;24106:32;;24198:4;24186:17;;;24180:24;24206:4;24176:35;24154:20;;;24147:65;24272:4;24260:17;;;24254:24;24280:6;24250:37;24228:20;;;24221:67;24344:4;24332:17;;;24326:24;24304:20;;;24297:54;;;;24093:3;24078:19;;24060:297;53970:809:0;;;;;;;;;;-1:-1:-1;53970:809:0;;;;;:::i;:::-;;:::i;:::-;;55737:1535;;;;;;;;;;-1:-1:-1;55737:1535:0;;;;;:::i;:::-;;:::i;61251:126::-;;;;;;;;;;;;;:::i;28229:2147::-;;;;;;;;;;-1:-1:-1;28229:2147:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;57372:1047::-;;;;;;;;;;-1:-1:-1;57372:1047:0;;;;;:::i;:::-;;:::i;26770:97::-;;;;;;;;;;-1:-1:-1;26810:6:0;26836:23;;;26770:97;;;25791:6:1;25779:19;;;25761:38;;25749:2;25734:18;26770:97:0;25716:89:1;30878:994:0;;;;;;;;;;-1:-1:-1;30878:994:0;;;;;:::i;:::-;;:::i;32062:1664::-;;;;;;;;;;-1:-1:-1;32062:1664:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;26999:119::-;;;;;;;;;;-1:-1:-1;27076:34:0;;26999:119;;60654:408;;;;;;:::i;:::-;;:::i;27652:212::-;;;;;;;;;;-1:-1:-1;27652:212:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;26633:129::-;;;;;;;;;;-1:-1:-1;26633:129:0;;;;;:::i;:::-;-1:-1:-1;;;;;26715:39:0;26691:4;26715:39;;;:33;:39;;;;;;;;;26633:129;26365:111;;;;;;;;;;-1:-1:-1;26444:24:0;;;;;;;26365:111;;54860:788;;;;;;;;;;-1:-1:-1;54860:788:0;;;;;:::i;:::-;;:::i;33851:155::-;;;;;;;;;;-1:-1:-1;33851:155:0;;;;;:::i;:::-;;:::i;26094:139::-;;;;;;;;;;-1:-1:-1;26094:139:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;26875:116::-;;;;;;;;;;-1:-1:-1;26925:6:0;26950:33;;;;;;26875:116;;24104:692;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24260:36:0;:19;-1:-1:-1;24260:29:0;:36::i;:::-;24248:48;;24307:11;24316:2;24307:11;;:::i;:::-;;-1:-1:-1;24343:34:0;:19;24307:11;24343:27;:34::i;:::-;24331:46;;:9;;;:46;24388:10;24397:1;24388:10;;:::i;:::-;;;24419:2;:9;;;:14;;24432:1;24419:14;24411:47;;;;-1:-1:-1;;;24411:47:0;;21609:2:1;24411:47:0;;;21591:21:1;21648:2;21628:18;;;21621:30;-1:-1:-1;;;21667:18:1;;;21660:50;21727:18;;24411:47:0;21581:170:1;24411:47:0;24482:35;:19;24511:5;24482:28;:35::i;:::-;24471:46;;:8;;;:46;24528:10;24537:1;24528:10;;:::i;:::-;;-1:-1:-1;24563:36:0;:19;24528:10;24563:29;:36::i;:::-;24551:9;;;:48;24610:11;24619:2;24610:11;;:::i;:::-;;-1:-1:-1;24649:36:0;:19;24610:11;24649:29;:36::i;:::-;24634:12;;;:51;24696:11;24705:2;24696:11;;:::i;:::-;;;24758:5;24728:19;:26;:35;24720:68;;;;-1:-1:-1;;;24720:68:0;;21609:2:1;24720:68:0;;;21591:21:1;21648:2;21628:18;;;21621:30;-1:-1:-1;;;21667:18:1;;;21660:50;21727:18;;24720:68:0;21581:170:1;24720:68:0;24104:692;;;;:::o;22302:1019::-;22385:29;;:::i;:::-;22427:10;22467:31;:14;22427:10;22467:24;:31::i;:::-;22454:44;;22509:11;22518:2;22509:11;;:::i;:::-;;-1:-1:-1;22546:29:0;:14;22509:11;22546:22;:29::i;:::-;22533:42;;:10;;;:42;22586:10;22595:1;22586:10;;:::i;:::-;;;22617:3;:10;;;:15;;22631:1;22617:15;22609:54;;;;-1:-1:-1;;;22609:54:0;;13373:2:1;22609:54:0;;;13355:21:1;13412:2;13392:18;;;13385:30;13451:28;13431:18;;;13424:56;13497:18;;22609:54:0;13345:176:1;22609:54:0;22688:30;:14;22712:5;22688:23;:30::i;:::-;22676:42;;:9;;;:42;22729:10;22738:1;22729:10;;:::i;:::-;;-1:-1:-1;22778:30:0;:14;22729:10;22778:23;:30::i;:::-;22752:56;;:23;;;:56;22819:10;22828:1;22819:10;;:::i;:::-;;-1:-1:-1;22842:20:0;22865:29;:14;22819:10;22865:22;:29::i;:::-;22842:52;-1:-1:-1;22905:10:0;22914:1;22905:10;;:::i;:::-;;;22949:116;;;;;;;;23005:14;22991:29;;-1:-1:-1;;;;;22991:29:0;;;;;-1:-1:-1;;;22991:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;22991:29:0;-1:-1:-1;22949:116:0;;23052:1;22949:116;;;;;;;22928:18;;;:137;;;;23078:154;23098:14;23094:18;;:1;:18;23078:154;;;23163:31;:14;23188:5;23163:24;:31::i;:::-;23134:18;;;;:23;:26;;23158:1;;23134:26;;;;-1:-1:-1;;;23134:26:0;;;;;;;;;-1:-1:-1;;;;;23134:60:0;;;:26;;;;;;;;;;;:60;23209:11;23218:2;23209:11;;:::i;:::-;;-1:-1:-1;23114:3:0;;;;:::i;:::-;;;;23078:154;;;;23277:5;23252:14;:21;:30;23244:69;;;;-1:-1:-1;;;23244:69:0;;13373:2:1;23244:69:0;;;13355:21:1;13412:2;13392:18;;;13385:30;13451:28;13431:18;;;13424:56;13497:18;;23244:69:0;13345:176:1;23244:69:0;22302:1019;;;;;:::o;21597:620::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21754:31:0;:14;-1:-1:-1;21754:24:0;:31::i;:::-;21742:43;;21796:11;21805:2;21796:11;;:::i;:::-;;-1:-1:-1;21832:29:0;:14;21796:11;21832:22;:29::i;:::-;21820:41;;:9;;;:41;21872:10;21881:1;21872:10;;:::i;:::-;;;21903:2;:9;;;:14;;21916:1;21903:14;21895:50;;;;-1:-1:-1;;;21895:50:0;;19807:2:1;21895:50:0;;;19789:21:1;19846:2;19826:18;;;19819:30;-1:-1:-1;;;19865:18:1;;;19858:53;19928:18;;21895:50:0;19779:173:1;21895:50:0;21969:30;:14;21993:5;21969:23;:30::i;:::-;21958:41;;:8;;;:41;22010:10;22019:1;22010:10;;:::i;:::-;;-1:-1:-1;22074:31:0;:14;22010:10;22074:24;:31::i;:::-;-1:-1:-1;;;;;22033:75:0;:14;;;:75;22119:11;22128:2;22119:11;;:::i;:::-;;;22176:5;22151:14;:21;:30;22143:66;;;;-1:-1:-1;;;22143:66:0;;19807:2:1;22143:66:0;;;19789:21:1;19846:2;19826:18;;;19819:30;-1:-1:-1;;;19865:18:1;;;19858:53;19928:18;;22143:66:0;19779:173:1;23400:626:0;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23561:37:0;:20;-1:-1:-1;23561:30:0;:37::i;:::-;23548:50;;23609:11;23618:2;23609:11;;:::i;:::-;;-1:-1:-1;23646:35:0;:20;23609:11;23646:28;:35::i;:::-;23633:48;;:10;;;:48;23692:10;23701:1;23692:10;;:::i;:::-;;;23723:3;:10;;;:15;;23737:1;23723:15;23715:49;;;;-1:-1:-1;;;23715:49:0;;16562:2:1;23715:49:0;;;16544:21:1;16601:2;16581:18;;;16574:30;-1:-1:-1;;;16620:18:1;;;16613:51;16681:18;;23715:49:0;16534:171:1;23715:49:0;23789:36;:20;23819:5;23789:29;:36::i;:::-;23777:48;;:9;;;:48;23836:10;23845:1;23836:10;;:::i;:::-;;-1:-1:-1;23876:37:0;:20;23836:10;23876:30;:37::i;:::-;23859:14;;;:54;23924:11;23933:2;23924:11;;:::i;:::-;;;23987:5;23956:20;:27;:36;23948:70;;;;-1:-1:-1;;;23948:70:0;;16562:2:1;23948:70:0;;;16544:21:1;16601:2;16581:18;;;16574:30;-1:-1:-1;;;16620:18:1;;;16613:51;16681:18;;23948:70:0;16534:171:1;53970:809:0;54037:20;54060:12;54068:3;54060:7;:12::i;:::-;54037:35;;54143:12;54157:20;54181:22;54200:2;54181:18;:22::i;:::-;54142:61;;;;54222:7;54231:6;54214:24;;;;;-1:-1:-1;;;54214:24:0;;;;;;;;:::i;:::-;;54251:48;54302:32;54323:2;:10;;;54302:20;:32::i;:::-;54401:14;;54251:83;;-1:-1:-1;53822:66:0;54401:24;54393:51;;;;-1:-1:-1;;;54393:51:0;;20159:2:1;54393:51:0;;;20141:21:1;20198:2;20178:18;;;20171:30;-1:-1:-1;;;20217:18:1;;;20210:44;20271:18;;54393:51:0;20131:164:1;54393:51:0;26810:6;26836:23;;;54510:26;;:7;:13;;;:26;;;54502:52;;;;-1:-1:-1;;;54502:52:0;;17676:2:1;54502:52:0;;;17658:21:1;17715:2;17695:18;;;17688:30;-1:-1:-1;;;17734:18:1;;;17727:43;17787:18;;54502:52:0;17648:163:1;54502:52:0;54620:36;54648:2;:7;;;54620:27;:36::i;:::-;54729:42;54751:7;:19;;;54729:21;:42::i;:::-;53970:809;;;;;:::o;55737:1535::-;55803:20;55826:12;55834:3;55826:7;:12::i;:::-;55803:35;;55909:12;55923:20;55947:22;55966:2;55947:18;:22::i;:::-;55908:61;;;;55988:7;55997:6;55980:24;;;;;-1:-1:-1;;;55980:24:0;;;;;;;;:::i;:::-;;56017:51;56071:35;56095:2;:10;;;56071:23;:35::i;:::-;56173:14;;56017:89;;-1:-1:-1;53822:66:0;56173:24;56165:51;;;;-1:-1:-1;;;56165:51:0;;18770:2:1;56165:51:0;;;18752:21:1;18809:2;18789:18;;;18782:30;-1:-1:-1;;;18828:18:1;;;18821:44;18882:18;;56165:51:0;18742:164:1;56165:51:0;26810:6;26836:23;;;56282:26;;:7;:13;;;:26;;;:48;;;-1:-1:-1;56312:13:0;;;;:18;;;56282:48;56274:74;;;;-1:-1:-1;;;56274:74:0;;14490:2:1;56274:74:0;;;14472:21:1;14529:2;14509:18;;;14502:30;-1:-1:-1;;;14548:18:1;;;14541:43;14601:18;;56274:74:0;14462:163:1;56274:74:0;56505:22;;;;:27;:34;56497:76;;;;-1:-1:-1;;;56497:76:0;;21255:2:1;56497:76:0;;;21237:21:1;21294:2;21274:18;;;21267:30;21333:27;21313:18;;;21306:55;21378:18;;56497:76:0;21227:175:1;56497:76:0;26326:23;;;;56704:32;;56735:1;56704:32;:::i;:::-;56673:63;;:7;:27;;;:63;;;56665:109;;;;-1:-1:-1;;;56665:109:0;;18368:2:1;56665:109:0;;;18350:21:1;18407:2;18387:18;;;18380:30;18446:34;18426:18;;;18419:62;-1:-1:-1;;;18497:18:1;;;18490:31;18538:19;;56665:109:0;18340:223:1;56665:109:0;56859:36;56887:2;:7;;;56859:27;:36::i;:::-;56971:47;56989:28;26326:23;;;;;26241:116;56989:28;56971:17;:47::i;:::-;57083:69;57100:7;:22;;;57124:7;:27;;;57083:16;:69::i;:::-;57236:27;;;;34204:23;:34;;-1:-1:-1;;34204:34:0;;;;;;;;;;;57213:51;34135:111;61251:126;61419:22;61444:35;47353:66;47714:54;-1:-1:-1;;;;;47714:54:0;;47634:142;61444:35;61419:60;;61515:29;61529:14;-1:-1:-1;;;;;26715:39:0;26691:4;26715:39;;;:33;:39;;;;;;;;;26633:129;61515:29;61514:30;61492:99;;;;-1:-1:-1;;;61492:99:0;;15864:2:1;61492:99:0;;;15846:21:1;15903:2;15883:18;;;15876:30;-1:-1:-1;;;15922:18:1;;;15915:49;15981:18;;61492:99:0;15836:169:1;61492:99:0;61604:30;61619:14;-1:-1:-1;;;;;34614:49:0;:6;:49;;;:33;:49;;;;;:56;;-1:-1:-1;;34614:56:0;34666:4;34614:56;;;34546:132;61604:30;61251:126;:::o;28229:2147::-;28290:10;28302:20;28418:38;28459:35;28474:2;:19;;;28459:14;:35::i;:::-;28961:16;;:23;28418:76;;-1:-1:-1;28958:97:0;;29013:5;29005:38;;;;;;;;;;;;;-1:-1:-1;;;29005:38:0;;;;;;;;28229:2147;;;:::o;28958:97::-;26326:23;;;;29183:51;;:2;:19;;;:51;;;;:99;;;;;29267:15;29238:11;:26;;;:44;;;29183:99;29180:172;;;29306:5;29298:42;;;;;;;;;;;;;;;;;;;;;;28229:2147;;;:::o;29180:172::-;29875:16;;:23;29868:31;;:6;:31::i;:::-;29845:2;:13;;;:20;:54;29841:113;;;29923:5;29915:27;;;;;;;;;;;;;-1:-1:-1;;;29915:27:0;;;;;;;;28229:2147;;;:::o;29841:113::-;30043:20;30065:27;30096:53;30113:2;:7;;;30122:2;:13;;;30137:11;30096:16;:53::i;:::-;30042:107;;;;30164:15;30160:76;;30203:5;;30210:13;;-1:-1:-1;28229:2147:0;-1:-1:-1;;;;28229:2147:0:o;30160:76::-;30359:4;30351:17;;;;;;;;;;;;;;;;;;;28229:2147;;;:::o;57372:1047::-;57436:20;57459:12;57467:3;57459:7;:12::i;:::-;57436:35;;57542:12;57556:20;57580:22;57599:2;57580:18;:22::i;:::-;57541:61;;;;57621:7;57630:6;57613:24;;;;;-1:-1:-1;;;57613:24:0;;;;;;;;:::i;:::-;;57704:46;57753:29;57771:2;:10;;;57753:17;:29::i;:::-;57849:15;;57704:78;;-1:-1:-1;53822:66:0;57849:25;57841:52;;;;-1:-1:-1;;;57841:52:0;;18770:2:1;57841:52:0;;;18752:21:1;18809:2;18789:18;;;18782:30;-1:-1:-1;;;18828:18:1;;;18821:44;18882:18;;57841:52:0;18742:164:1;57841:52:0;26810:6;26836:23;;;57959:27;;:8;:14;;;:27;;;:50;;;-1:-1:-1;57990:14:0;;;;:19;;;57959:50;57951:76;;;;-1:-1:-1;;;57951:76:0;;14490:2:1;57951:76:0;;;14472:21:1;14529:2;14509:18;;;14502:30;-1:-1:-1;;;14548:18:1;;;14541:43;14601:18;;57951:76:0;14462:163:1;57951:76:0;58112:36;58140:2;:7;;;58112:27;:36::i;:::-;58288:18;;;;58395:15;;;;58376:35;;-1:-1:-1;;;;;58376:18:0;;;:35;;;;;58228:25;58376:35;58228:25;58376:35;58395:15;58376:18;:35;;;;;;;;;;;;;;;;;;;;;57372:1047;;;;;;:::o;30878:994::-;31018:10;31030:20;31063:15;31098:6;31093:629;31114:10;:17;31110:1;:21;31093:629;;;31153:28;31184:10;31195:1;31184:13;;;;;;-1:-1:-1;;;31184:13:0;;;;;;;;;;;;;;;31153:44;;31297:1;31302;31297:6;:39;;;;31327:9;31307:29;;:3;:17;;;:29;;;31297:39;31289:87;;;;-1:-1:-1;;;31289:87:0;;20502:2:1;31289:87:0;;;20484:21:1;20541:2;20521:18;;;20514:30;20580:34;20560:18;;;20553:62;-1:-1:-1;;;20631:18:1;;;20624:33;20674:19;;31289:87:0;20474:225:1;31289:87:0;31403:17;;;;31602:16;;:35;;31403:17;;-1:-1:-1;31602:16:0;:35;;;;;;;;-1:-1:-1;;;31602:35:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;31562:75:0;:36;31572:4;31578:3;:5;;;31585:3;:5;;;31592:3;:5;;;31562:36;;;;;;;;;;;;;;;;;12771:25:1;;;12844:4;12832:17;;;;12827:2;12812:18;;12805:45;12881:2;12866:18;;12859:34;12924:2;12909:18;;12902:34;12758:3;12743:19;;12725:217;31562:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;31562:75:0;;31559:152;;31665:5;31657:38;;;;;;;;;;;;;-1:-1:-1;;;31657:38:0;;;;;;;;;;;;31559:152;-1:-1:-1;31133:3:0;;;;:::i;:::-;;;;31093:629;;;;31855:4;31847:17;;;;;;;;;;;;;;;;;30878:994;;;;;;;:::o;32062:1664::-;32132:20;;:::i;:::-;32165:10;32205:24;:9;32165:10;32205:17;:24::i;:::-;32192:37;;;;32240:10;32249:1;32240:10;;:::i;:::-;;;32269:2;:10;;;:15;;32283:1;32269:15;32261:51;;;;-1:-1:-1;;;32261:51:0;;22298:2:1;32261:51:0;;;22280:21:1;22337:2;22317:18;;;22310:30;22376:25;22356:18;;;22349:53;22419:18;;32261:51:0;22270:173:1;32261:51:0;32347:25;:9;32366:5;32347:18;:25::i;:::-;32325:47;;:19;;;:47;32383:10;32392:1;32383:10;;:::i;:::-;;-1:-1:-1;32435:18:0;32456:24;:9;32383:10;32456:17;:24::i;:::-;32435:45;;;-1:-1:-1;32491:10:0;32500:1;32491:10;;:::i;:::-;;;32552;-1:-1:-1;;;;;32528:35:0;;;;;-1:-1:-1;;;32528:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32528:35:0;;-1:-1:-1;;32528:35:0;;;;;;;;;;;-1:-1:-1;32512:13:0;;;:51;32579:6;32574:415;32595:10;32591:1;:14;32574:415;;;32660:24;:9;32678:5;32660:17;:24::i;:::-;32627:2;:13;;;32641:1;32627:16;;;;;;-1:-1:-1;;;32627:16:0;;;;;;;;;;;;;;;;;;;:57;;;;:30;;;;:57;32699:10;32708:1;32699:10;;:::i;:::-;;-1:-1:-1;32747:26:0;:9;32699:10;32747:19;:26::i;:::-;32726:2;:13;;;32740:1;32726:16;;;;;;-1:-1:-1;;;32726:16:0;;;;;;;;;;;;;;;:18;;:47;;;;;32797:2;32788:11;;;;;:::i;:::-;;-1:-1:-1;32835:26:0;:9;32788:11;32835:19;:26::i;:::-;32814:2;:13;;;32828:1;32814:16;;;;;;-1:-1:-1;;;32814:16:0;;;;;;;;;;;;;;;:18;;:47;;;;;32885:2;32876:11;;;;;:::i;:::-;;-1:-1:-1;32923:24:0;:9;32876:11;32923:17;:24::i;:::-;:29;;32950:2;32923:29;:::i;:::-;32902:2;:13;;;32916:1;32902:16;;;;;;-1:-1:-1;;;32902:16:0;;;;;;;;;;;;;;;;;;;:50;;;;:18;;;;:50;32967:10;32976:1;32967:10;;:::i;:::-;;-1:-1:-1;32607:3:0;;;;:::i;:::-;;;;32574:415;;;;33027:17;33047:48;33063:5;33089;33070:9;:16;:24;;;;:::i;:::-;33047:9;;:48;:15;:48::i;:::-;33027:68;;33153:4;33143:15;;;;;;33126:33;;;;;;11528:19:1;;11572:2;11563:12;;11518:63;33126:33:0;;;;-1:-1:-1;;33126:33:0;;;;;;;;;33116:44;;33126:33;33116:44;;;;33106:7;;;:54;33215:25;:9;33234:5;33215:18;:25::i;:::-;33200:40;;:12;;;:40;33251:10;33260:1;33251:10;;:::i;:::-;;-1:-1:-1;33285:25:0;:9;33251:10;33285:18;:25::i;:::-;33274:36;;:8;;;:36;33321:10;33330:1;33321:10;;:::i;:::-;;-1:-1:-1;33364:25:0;:9;33321:10;33364:18;:25::i;:::-;33344:45;;:17;;;:45;33400:10;33409:1;33400:10;;:::i;:::-;;-1:-1:-1;33443:26:0;:9;33400:10;33443:19;:26::i;:::-;33423:17;;;:46;33480:11;33489:2;33480:11;;:::i;:::-;;-1:-1:-1;33518:25:0;:9;33480:11;33518:18;:25::i;:::-;-1:-1:-1;;;;;33504:39:0;:11;;;:39;33554:10;33563:1;33554:10;;:::i;:::-;;-1:-1:-1;33599:24:0;:9;33554:10;33599:17;:24::i;:::-;33577:46;;:19;;;:46;33634:10;33643:1;33634:10;;:::i;:::-;;;33670:48;33686:5;33712;33693:9;:16;:24;;;;:::i;33670:48::-;33657:10;;;:61;-1:-1:-1;33657:2:0;;32062:1664;-1:-1:-1;;;32062:1664:0:o;60654:408::-;60796:15;60867:12;27196:17;;;27126:95;60867:12;60854:9;:25;60846:49;;;;-1:-1:-1;;;60846:49:0;;15181:2:1;60846:49:0;;;15163:21:1;15220:2;15200:18;;;15193:30;-1:-1:-1;;;15239:18:1;;;15232:41;15290:18;;60846:49:0;15153:161:1;60846:49:0;60919:23;60931:10;60919:11;:23::i;:::-;60908:34;;60999:10;-1:-1:-1;;;;;60979:75:0;;61011:8;61021:5;61028:7;61037:16;60979:75;;;;;;;;;:::i;:::-;;;;;;;;60654:408;;;;;:::o;27652:212::-;27725:20;;:::i;:::-;27747:10;27759:20;27797:18;27805:9;;27797:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;27797:7:0;;-1:-1:-1;;;27797:18:0:i;:::-;27792:23;;27844:12;27853:2;27844:8;:12::i;:::-;27652:212;;27826:30;;-1:-1:-1;27826:30:0;;-1:-1:-1;;;27652:212:0:o;54860:788::-;54925:20;54948:12;54956:3;54948:7;:12::i;:::-;54925:35;;55031:12;55045:20;55069:22;55088:2;55069:18;:22::i;:::-;55030:61;;;;55110:7;55119:6;55102:24;;;;;-1:-1:-1;;;55102:24:0;;;;;;;;:::i;:::-;;55139:46;55188:30;55207:2;:10;;;55188:18;:30::i;:::-;55285:14;;55139:79;;-1:-1:-1;53822:66:0;55285:24;55277:51;;;;-1:-1:-1;;;55277:51:0;;20159:2:1;55277:51:0;;;20141:21:1;20198:2;20178:18;;;20171:30;-1:-1:-1;;;20217:18:1;;;20210:44;20271:18;;55277:51:0;20131:164:1;55277:51:0;26810:6;26836:23;;;55394:26;;:7;:13;;;:26;;;55386:52;;;;-1:-1:-1;;;55386:52:0;;17676:2:1;55386:52:0;;;17658:21:1;17715:2;17695:18;;;17688:30;-1:-1:-1;;;17734:18:1;;;17727:43;17787:18;;55386:52:0;17648:163:1;55386:52:0;55523:36;55551:2;:7;;;55523:27;:36::i;:::-;55607:33;55621:7;:18;;;35257:17;:26;35198:93;33851:155;33915:35;33992:1;33972:16;:12;33987:1;33972:16;:::i;:::-;33971:22;;;;:::i;:::-;33970:28;;33997:1;33970:28;:::i;:::-;33963:35;33851:155;-1:-1:-1;;33851:155:0:o;26094:139::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;26199:26:0;;;;;:19;:26;;;;;;26192:33;;;;;;;;;;;;;;;;;;;-1:-1:-1;;26192:33:0;26199:26;;26192:33;;26199:26;;26192:33;;26199:26;26192:33;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;26192:33:0;;;;;;;;;;;;;;;;-1:-1:-1;;;26192:33:0;;;-1:-1:-1;;26192:33:0;;;;;;;;;;;;;;26094:139;-1:-1:-1;;26094:139:0:o;15904:329::-;15983:7;16028:11;:6;16037:2;16028:11;:::i;:::-;16011:6;:13;:28;;16003:62;;;;-1:-1:-1;;;16003:62:0;;16912:2:1;16003:62:0;;;16894:21:1;16951:2;16931:18;;;16924:30;-1:-1:-1;;;16970:18:1;;;16963:51;17031:18;;16003:62:0;16884:171:1;16003:62:0;-1:-1:-1;16153:30:0;16169:4;16153:30;16147:37;;15904:329::o;13640:311::-;13717:5;13760:10;:6;13769:1;13760:10;:::i;:::-;13743:6;:13;:27;;13735:60;;;;-1:-1:-1;;;13735:60:0;;19459:2:1;13735:60:0;;;19441:21:1;19498:2;19478:18;;;19471:30;-1:-1:-1;;;19517:18:1;;;19510:49;19576:18;;13735:60:0;19431:169:1;13735:60:0;-1:-1:-1;13875:29:0;13891:3;13875:29;13869:36;;13640:311::o;13959:314::-;14037:6;14081:10;:6;14090:1;14081:10;:::i;:::-;14064:6;:13;:27;;14056:60;;;;-1:-1:-1;;;14056:60:0;;13728:2:1;14056:60:0;;;13710:21:1;13767:2;13747:18;;;13740:30;-1:-1:-1;;;13786:18:1;;;13779:50;13846:18;;14056:60:0;13700:170:1;14056:60:0;-1:-1:-1;14197:29:0;14213:3;14197:29;14191:36;;13959:314::o;15576:320::-;15655:7;15700:11;:6;15709:2;15700:11;:::i;:::-;15683:6;:13;:28;;15675:62;;;;-1:-1:-1;;;15675:62:0;;16212:2:1;15675:62:0;;;16194:21:1;16251:2;16231:18;;;16224:30;-1:-1:-1;;;16270:18:1;;;16263:51;16331:18;;15675:62:0;16184:171:1;14281:314:0;14359:6;14403:10;:6;14412:1;14403:10;:::i;:::-;14386:6;:13;:27;;14378:60;;;;-1:-1:-1;;;14378:60:0;;20906:2:1;14378:60:0;;;20888:21:1;20945:2;20925:18;;;20918:30;-1:-1:-1;;;20964:18:1;;;20957:50;21024:18;;14378:60:0;20878:170:1;14378:60:0;-1:-1:-1;14519:29:0;14535:3;14519:29;14513:36;;14281:314::o;13269:363::-;13348:7;13393:11;:6;13402:2;13393:11;:::i;:::-;13376:6;:13;:28;;13368:62;;;;-1:-1:-1;;;13368:62:0;;18018:2:1;13368:62:0;;;18000:21:1;18057:2;18037:18;;;18030:30;-1:-1:-1;;;18076:18:1;;;18069:51;18137:18;;13368:62:0;17990:171:1;13368:62:0;-1:-1:-1;13522:30:0;13538:4;13522:30;13516:37;-1:-1:-1;;;13512:71:0;;;13269:363::o;59085:1221::-;59158:4;59164:13;59226:12;59240:20;59264:12;59273:2;59264:8;:12::i;:::-;59225:51;;;;59292:7;59287:62;;59323:5;;59330:6;;-1:-1:-1;59085:1221:0;-1:-1:-1;;;59085:1221:0:o;59287:62::-;26326:23;;;;59430:51;;:2;:19;;;:51;;;59426:136;;59506:5;59498:52;;;;;;;;;;;;;;;;;;;;;;;59085:1221;;;:::o;59426:136::-;26925:6;26950:33;;;;;;59643:48;;59650:2;:17;;;59643:48;;;59639:121;;59716:5;59708:40;;;;;;;;;;;;;-1:-1:-1;;;59708:40:0;;;;;;;;;59085:1221;;;:::o;59639:121::-;27076:34;;59861:2;:17;;;:41;59857:117;;59927:5;59919:43;;;;;;;;;;;;;;;;;;;;;;;59085:1221;;;:::o;59857:117::-;60130:7;;;;26555:4;26579:38;;;:32;:38;;;;;;;;60099:119;;;60162:5;60154:52;;;;;;;;;;;;;;;;;;;;;;;59085:1221;;;:::o;60099:119::-;60289:4;60281:17;;;;;;;;;;;;;;;;;;59085:1221;;;:::o;34686:124::-;34757:6;:38;;;:32;:38;;;;;:45;;-1:-1:-1;;34757:45:0;34798:4;34757:45;;;34686:124::o;58522:486::-;58600:29;58632:20;47353:66;47714:54;-1:-1:-1;;;;;47714:54:0;;47634:142;58632:20;58600:52;;58665:29;58676:17;58665:10;:29::i;:::-;58839:39;;;;;;;;;;;;;;;;-1:-1:-1;;;;;58839:39:0;-1:-1:-1;;;58839:39:0;;;58808:71;;58771:12;;;;-1:-1:-1;;;;;58808:30:0;;;:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58770:109;;;;58900:7;58916:6;58892:32;;;;;-1:-1:-1;;;58892:32:0;;;;;;;;:::i;:::-;;58982:17;-1:-1:-1;;;;;58942:58:0;58959:21;-1:-1:-1;;;;;58942:58:0;;;;;;;;;;;58522:486;;;;:::o;34254:144::-;34359:31;34366:15;34385:5;34359:31;:::i;:::-;34315:26;;;;:6;:26;;;:19;:26;;;;;:41;;:75;;-1:-1:-1;;34315:75:0;;;;;;;;34254:144::o;34406:132::-;34498:26;;;:6;:26;;;:19;:26;;;;;;;;:32;;;;34527:3;;34498:32;;:26;;:32;;;;:::i;:::-;-1:-1:-1;34498:32:0;;;;;;;;;;;;-1:-1:-1;;34498:32:0;;;;;;;;;;;-1:-1:-1;;34406:132:0:o;10390:2871::-;10543:12;10597:7;10581:12;10597:7;10591:2;10581:12;:::i;:::-;:23;;10573:50;;;;-1:-1:-1;;;10573:50:0;;15521:2:1;10573:50:0;;;15503:21:1;15560:2;15540:18;;;15533:30;-1:-1:-1;;;15579:18:1;;;15572:44;15633:18;;10573:50:0;15493:164:1;10573:50:0;10659:16;10668:7;10659:6;:16;:::i;:::-;10642:6;:13;:33;;10634:63;;;;-1:-1:-1;;;10634:63:0;;19113:2:1;10634:63:0;;;19095:21:1;19152:2;19132:18;;;19125:30;-1:-1:-1;;;19171:18:1;;;19164:47;19228:18;;10634:63:0;19085:167:1;10634:63:0;10710:22;10776:15;;10805:2005;;;;12954:4;12948:11;12935:24;;13143:1;13132:9;13125:20;13193:4;13182:9;13178:20;13172:4;13165:34;10769:2445;;10805:2005;10990:4;10984:11;10971:24;;11659:2;11650:7;11646:16;12047:9;12040:17;12034:4;12030:28;12018:9;12007;12003:25;11999:60;12096:7;12092:2;12088:16;12353:6;12339:9;12332:17;12326:4;12322:28;12310:9;12302:6;12298:22;12294:57;12290:70;12124:434;12387:3;12383:2;12380:11;12124:434;;;12529:9;;12518:21;;12429:4;12421:13;;;;12462;12124:434;;;-1:-1:-1;;12578:26:0;;;12790:2;12773:11;-1:-1:-1;;12769:25:0;12763:4;12756:39;-1:-1:-1;10769:2445:0;-1:-1:-1;13244:9:0;10390:2871;-1:-1:-1;;;;10390:2871:0:o;14603:314::-;14681:6;14725:10;:6;14734:1;14725:10;:::i;:::-;14708:6;:13;:27;;14700:60;;;;-1:-1:-1;;;14700:60:0;;14832:2:1;14700:60:0;;;14814:21:1;14871:2;14851:18;;;14844:30;-1:-1:-1;;;14890:18:1;;;14883:50;14950:18;;14700:60:0;14804:170:1;14700:60:0;-1:-1:-1;14841:29:0;14857:3;14841:29;14835:36;;14603:314::o;61070:173::-;-1:-1:-1;;;;;27315:25:0;;61126:15;27315:25;;;:16;:25;;;;;;-1:-1:-1;;;;;27315:25:0;61197:38;27315:25;61222:12;27315:25;61233:1;61222:12;:::i;:::-;-1:-1:-1;;;;;35378:25:0;;;;:6;:25;;;:16;:25;;;;;:36;;-1:-1:-1;;35378:36:0;-1:-1:-1;;;;;35378:36:0;;;;;;;;;35299:123;61197:38;61070:173;;;:::o;48247:155::-;48314:37;48333:17;48314:18;:37::i;:::-;48367:27;;-1:-1:-1;;;;;48367:27:0;;;;;;;;48247:155;:::o;47872:262::-;36951:20;;47946:95;;;;-1:-1:-1;;;47946:95:0;;17262:2:1;47946:95:0;;;17244:21:1;17301:2;17281:18;;;17274:30;17340:34;17320:18;;;17313:62;-1:-1:-1;;;17391:18:1;;;17384:43;17444:19;;47946:95:0;17234:235:1;47946:95:0;47353:66;48052:74;;-1:-1:-1;;;;;;48052:74:0;-1:-1:-1;;;;;48052:74:0;;;;;;;;;;47872:262::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:173:1;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:2;;177:1;174;167:12;192:1120;255:5;308:3;301:4;293:6;289:17;285:27;275:2;;330:5;323;316:20;275:2;370:6;357:20;396:4;420:60;436:43;476:2;436:43;:::i;:::-;420:60;:::i;:::-;502:3;526:2;521:3;514:15;554:2;549:3;545:12;538:19;;589:2;581:6;577:15;641:3;636:2;630;627:1;623:10;615:6;611:23;607:32;604:41;601:2;;;662:5;655;648:20;601:2;688:5;702:581;716:2;713:1;710:9;702:581;;;771:4;810:2;804:3;799;795:13;791:22;788:2;;;830:5;823;816:20;788:2;864:22;;:::i;:::-;926:3;913:17;906:5;899:32;989:2;984:3;980:12;967:26;962:2;955:5;951:14;944:50;1017:2;1055:30;1081:2;1076:3;1072:12;1055:30;:::i;:::-;1039:14;;;1032:54;1109:2;1147:30;1164:12;;;1147:30;:::i;:::-;1131:14;;;1124:54;1191:18;;1229:12;;;;1261;;;;;734:1;727:9;702:581;;;-1:-1:-1;1301:5:1;;265:1047;-1:-1:-1;;;;;;;265:1047:1:o;1317:550::-;1359:5;1412:3;1405:4;1397:6;1393:17;1389:27;1379:2;;1434:5;1427;1420:20;1379:2;1474:6;1461:20;-1:-1:-1;;;;;1496:2:1;1493:26;1490:2;;;1522:18;;:::i;:::-;1566:55;1609:2;1590:13;;-1:-1:-1;;1586:27:1;1615:4;1582:38;1566:55;:::i;:::-;1646:2;1637:7;1630:19;1692:3;1685:4;1680:2;1672:6;1668:15;1664:26;1661:35;1658:2;;;1713:5;1706;1699:20;1658:2;1782;1775:4;1767:6;1763:17;1756:4;1747:7;1743:18;1730:55;1805:16;;;1823:4;1801:27;1794:42;;;;1809:7;1369:498;-1:-1:-1;;1369:498:1:o;1872:159::-;1939:20;;1999:6;1988:18;;1978:29;;1968:2;;2021:1;2018;2011:12;2036:163;2103:20;;2163:10;2152:22;;2142:33;;2132:2;;2189:1;2186;2179:12;2204:171;2271:20;;-1:-1:-1;;;;;2320:30:1;;2310:41;;2300:2;;2365:1;2362;2355:12;2380:156;2446:20;;2506:4;2495:16;;2485:27;;2475:2;;2526:1;2523;2516:12;2541:196;2600:6;2653:2;2641:9;2632:7;2628:23;2624:32;2621:2;;;2674:6;2666;2659:22;2621:2;2702:29;2721:9;2702:29;:::i;:::-;2692:39;2611:126;-1:-1:-1;;;2611:126:1:o;2742:190::-;2801:6;2854:2;2842:9;2833:7;2829:23;2825:32;2822:2;;;2875:6;2867;2860:22;2822:2;-1:-1:-1;2903:23:1;;2812:120;-1:-1:-1;2812:120:1:o;2937:1646::-;3091:6;3099;3107;3160:2;3148:9;3139:7;3135:23;3131:32;3128:2;;;3181:6;3173;3166:22;3128:2;3222:9;3209:23;3199:33;;3251:2;3304;3293:9;3289:18;3276:32;-1:-1:-1;;;;;3368:2:1;3360:6;3357:14;3354:2;;;3389:6;3381;3374:22;3354:2;3417:70;3479:7;3470:6;3459:9;3455:22;3417:70;:::i;:::-;3407:80;;3540:2;3529:9;3525:18;3512:32;3496:48;;3569:2;3559:8;3556:16;3553:2;;;3590:6;3582;3575:22;3553:2;3618:24;;;;3676:2;3658:16;;;3654:25;3651:2;;;3697:6;3689;3682:22;3651:2;3728:22;;:::i;:::-;3788:2;3775:16;3816:2;3806:8;3803:16;3800:2;;;3837:6;3829;3822:22;3800:2;3865:17;;;-1:-1:-1;3913:4:1;3905:13;;3901:27;-1:-1:-1;3891:2:1;;3947:6;3939;3932:22;3891:2;3988;3975:16;4011:60;4027:43;4067:2;4027:43;:::i;4011:60::-;4093:3;4117:2;4112:3;4105:15;4145:2;4140:3;4136:12;4129:19;;4176:2;4172;4168:11;4224:7;4219:2;4213;4210:1;4206:10;4202:2;4198:19;4194:28;4191:41;4188:2;;;4250:6;4242;4235:22;4188:2;4277:6;4268:15;;4292:169;4306:2;4303:1;4300:9;4292:169;;;4363:23;4382:3;4363:23;:::i;:::-;4351:36;;4324:1;4317:9;;;;;4407:12;;;;4439;;4292:169;;;-1:-1:-1;4470:20:1;;-1:-1:-1;4522:30:1;;-1:-1:-1;4540:11:1;;;4522:30;:::i;:::-;4517:2;4510:5;4506:14;4499:54;4572:5;4562:15;;;;;;3118:1465;;;;;:::o;4588:641::-;4658:6;4666;4719:2;4707:9;4698:7;4694:23;4690:32;4687:2;;;4740:6;4732;4725:22;4687:2;4785:9;4772:23;-1:-1:-1;;;;;4855:2:1;4847:6;4844:14;4841:2;;;4876:6;4868;4861:22;4841:2;4919:6;4908:9;4904:22;4894:32;;4964:7;4957:4;4953:2;4949:13;4945:27;4935:2;;4991:6;4983;4976:22;4935:2;5036;5023:16;5062:2;5054:6;5051:14;5048:2;;;5083:6;5075;5068:22;5048:2;5133:7;5128:2;5119:6;5115:2;5111:15;5107:24;5104:37;5101:2;;;5159:6;5151;5144:22;5101:2;5195;5187:11;;;;;5217:6;;-1:-1:-1;4677:552:1;;-1:-1:-1;;;;4677:552:1:o;5234:340::-;5302:6;5355:2;5343:9;5334:7;5330:23;5326:32;5323:2;;;5376:6;5368;5361:22;5323:2;5421:9;5408:23;-1:-1:-1;;;;;5446:6:1;5443:30;5440:2;;;5491:6;5483;5476:22;5440:2;5519:49;5560:7;5551:6;5540:9;5536:22;5519:49;:::i;:::-;5509:59;5313:261;-1:-1:-1;;;;5313:261:1:o;5579:1475::-;5656:6;5709:2;5697:9;5688:7;5684:23;5680:32;5677:2;;;5730:6;5722;5715:22;5677:2;5775:9;5762:23;-1:-1:-1;;;;;5845:2:1;5837:6;5834:14;5831:2;;;5866:6;5858;5851:22;5831:2;5894:22;;;;5950:6;5932:16;;;5928:29;5925:2;;;5975:6;5967;5960:22;5925:2;6006:22;;:::i;:::-;6051:20;6068:2;6051:20;:::i;:::-;6044:5;6037:35;6104:30;6130:2;6126;6122:11;6104:30;:::i;:::-;6099:2;6092:5;6088:14;6081:54;6167:30;6193:2;6189;6185:11;6167:30;:::i;:::-;6162:2;6155:5;6151:14;6144:54;6230:30;6256:2;6252;6248:11;6230:30;:::i;:::-;6225:2;6218:5;6214:14;6207:54;6315:3;6311:2;6307:12;6294:26;6288:3;6281:5;6277:15;6270:51;6354:31;6380:3;6376:2;6372:12;6354:31;:::i;:::-;6348:3;6341:5;6337:15;6330:56;6419:30;6444:3;6440:2;6436:12;6419:30;:::i;:::-;6413:3;6406:5;6402:15;6395:55;6496:3;6492:2;6488:12;6475:26;6526:2;6516:8;6513:16;6510:2;;;6547:6;6539;6532:22;6510:2;6589:44;6625:7;6614:8;6610:2;6606:17;6589:44;:::i;:::-;6583:3;6576:5;6572:15;6565:69;;6653:3;6688:30;6714:2;6710;6706:11;6688:30;:::i;:::-;6672:14;;;6665:54;6738:3;6779:11;;;6766:25;6803:16;;;6800:2;;;6837:6;6829;6822:22;6800:2;6878:65;6935:7;6924:8;6920:2;6916:17;6878:65;:::i;:::-;6862:14;;;6855:89;;;;-1:-1:-1;6963:3:1;7011:11;;;6998:25;6982:14;;;6975:49;;;;-1:-1:-1;6866:5:1;5667:1387;-1:-1:-1;;;5667:1387:1:o;7254:194::-;7312:6;7365:2;7353:9;7344:7;7340:23;7336:32;7333:2;;;7386:6;7378;7371:22;7333:2;7414:28;7432:9;7414:28;:::i;7453:482::-;7536:6;7544;7552;7605:2;7593:9;7584:7;7580:23;7576:32;7573:2;;;7626:6;7618;7611:22;7573:2;7654:28;7672:9;7654:28;:::i;:::-;7644:38;;7733:2;7722:9;7718:18;7705:32;-1:-1:-1;;;;;7752:6:1;7749:30;7746:2;;;7797:6;7789;7782:22;7746:2;7825:49;7866:7;7857:6;7846:9;7842:22;7825:49;:::i;:::-;7815:59;;;7893:36;7925:2;7914:9;7910:18;7893:36;:::i;:::-;7883:46;;7563:372;;;;;:::o;7940:783::-;8002:3;8040:5;8034:12;8067:6;8062:3;8055:19;8093:4;8122:2;8117:3;8113:12;8106:19;;8159:2;8152:5;8148:14;8180:3;8192:506;8206:6;8203:1;8200:13;8192:506;;;8265:13;;8303:9;;8291:22;;8353:11;;;8347:18;8333:12;;;8326:40;8389:4;8432:11;;;8426:18;8467:4;8505:21;;;8491:12;;;8484:43;;;;8550:4;8598:11;;;8592:18;8588:27;8574:12;;;8567:49;8645:4;8636:14;;;;8673:15;;;;8228:1;8221:9;8192:506;;;-1:-1:-1;8714:3:1;;8010:713;-1:-1:-1;;;;;8010:713:1:o;8728:257::-;8769:3;8807:5;8801:12;8834:6;8829:3;8822:19;8850:63;8906:6;8899:4;8894:3;8890:14;8883:4;8876:5;8872:16;8850:63;:::i;:::-;8967:2;8946:15;-1:-1:-1;;8942:29:1;8933:39;;;;8974:4;8929:50;;8777:208;-1:-1:-1;;8777:208:1:o;8990:686::-;9117:12;;9083:4;9138:17;;;9204:19;;9074:14;;;9232:20;;;9044:3;;9301:4;;9328:21;;;;9279:2;9270:12;;;9044:3;9379:201;9393:6;9390:1;9387:13;9379:201;;;9460:13;;-1:-1:-1;;;;;9456:39:1;9442:54;;9555:15;;;;9518:14;;;;9492:1;9408:9;9379:201;;;-1:-1:-1;;9620:14:1;;;9614:21;9637:10;9610:38;9596:12;;;;9589:60;;;;-1:-1:-1;9665:5:1;9052:624;-1:-1:-1;9052:624:1:o;9681:1332::-;9786:12;;11386:4;11375:16;11363:29;;9726:3;9754:6;9850:4;9843:5;9839:16;9833:23;9865:47;9906:4;9901:3;9897:14;9883:12;11189:10;11178:22;11166:35;;11156:51;9865:47;;9960:4;9953:5;9949:16;9943:23;9975:49;10018:4;10013:3;10009:14;9993;11189:10;11178:22;11166:35;;11156:51;9975:49;;10072:4;10065:5;10061:16;10055:23;10087:49;10130:4;10125:3;10121:14;10105;11094:6;11083:18;11071:31;;11061:47;10087:49;;10185:4;10178:5;10174:16;10168:23;10161:4;10156:3;10152:14;10145:47;10240:4;10233:5;10229:16;10223:23;10255:49;10298:4;10293:3;10289:14;10273;-1:-1:-1;;;;;11277:30:1;11265:43;;11255:59;10255:49;;10352:4;10345:5;10341:16;10335:23;10367:48;10409:4;10404:3;10400:14;10384;11386:4;11375:16;11363:29;;11361:33;10367:48;;10463:4;10456:5;10452:16;10446:23;10501:2;10494:4;10489:3;10485:14;10478:26;10525:46;10567:2;10562:3;10558:12;10542:14;10525:46;:::i;:::-;10513:58;;;10590:6;10644:2;10637:5;10633:14;10627:21;10657:47;10700:2;10695:3;10691:12;10675:14;11189:10;11178:22;11166:35;;11156:51;10657:47;;;10723:6;10777:2;10770:5;10766:14;10760:21;10821:3;10815:4;10811:14;10806:2;10801:3;10797:12;10790:36;10849:59;10903:4;10887:14;10849:59;:::i;:::-;10927:6;10969:14;;;10963:21;10949:12;;;;10942:43;;;;-1:-1:-1;10835:73:1;;9734:1279;-1:-1:-1;;;9734:1279:1:o;11586:274::-;11715:3;11753:6;11747:13;11769:53;11815:6;11810:3;11803:4;11795:6;11791:17;11769:53;:::i;:::-;11838:16;;;;;11723:137;-1:-1:-1;;11723:137:1:o;12057:300::-;12242:6;12235:14;12228:22;12217:9;12210:41;12287:2;12282;12271:9;12267:18;12260:30;12191:4;12307:44;12347:2;12336:9;12332:18;12324:6;12307:44;:::i;12947:219::-;13096:2;13085:9;13078:21;13059:4;13116:44;13156:2;13145:9;13141:18;13133:6;13116:44;:::i;22941:682::-;23140:2;23129:9;23122:21;23185:6;23179:13;23174:2;23163:9;23159:18;23152:41;23257:4;23251:2;23243:6;23239:15;23233:22;23229:33;23224:2;23213:9;23209:18;23202:61;23327:6;23321:2;23313:6;23309:15;23303:22;23299:35;23294:2;23283:9;23279:18;23272:63;23103:4;23382:2;23374:6;23370:15;23364:22;23423:4;23417:3;23406:9;23402:19;23395:33;23451:64;23510:3;23499:9;23495:19;23481:12;23451:64;:::i;:::-;23437:78;;23582:10;23575:3;23567:6;23563:16;23557:23;23553:40;23546:4;23535:9;23531:20;23524:70;23611:6;23603:14;;;23112:511;;;;:::o;23628:266::-;23811:2;23800:9;23793:21;23774:4;23831:57;23884:2;23873:9;23869:18;23861:6;23831:57;:::i;24886:239::-;25051:2;25040:9;25033:21;25014:4;25071:48;25115:2;25104:9;25100:18;25092:6;25071:48;:::i;25130:482::-;25365:2;25354:9;25347:21;25328:4;25391:48;25435:2;25424:9;25420:18;25412:6;25391:48;:::i;:::-;25489:6;25482:14;25475:22;25470:2;25459:9;25455:18;25448:50;25546:9;25538:6;25534:22;25529:2;25518:9;25514:18;25507:50;25574:32;25599:6;25591;25574:32;:::i;:::-;25566:40;25337:275;-1:-1:-1;;;;;;25337:275:1:o;26394:477::-;-1:-1:-1;;;;;26621:6:1;26617:31;26606:9;26599:50;26697:10;26689:6;26685:23;26680:2;26669:9;26665:18;26658:51;26745:3;26740:2;26729:9;26725:18;26718:31;26580:4;26766:45;26806:3;26795:9;26791:19;26783:6;26766:45;:::i;:::-;26758:53;;26859:4;26851:6;26847:17;26842:2;26831:9;26827:18;26820:45;26589:282;;;;;;;:::o;26876:253::-;26948:2;26942:9;26990:4;26978:17;;-1:-1:-1;;;;;27010:34:1;;27046:22;;;27007:62;27004:2;;;27072:18;;:::i;:::-;27108:2;27101:22;26922:207;:::o;27134:251::-;27206:2;27200:9;;;27236:15;;-1:-1:-1;;;;;27266:34:1;;27302:22;;;27263:62;27260:2;;;27328:18;;:::i;27390:255::-;27462:2;27456:9;27504:6;27492:19;;-1:-1:-1;;;;;27526:34:1;;27562:22;;;27523:62;27520:2;;;27588:18;;:::i;27650:275::-;27721:2;27715:9;27786:2;27767:13;;-1:-1:-1;;27763:27:1;27751:40;;-1:-1:-1;;;;;27806:34:1;;27842:22;;;27803:62;27800:2;;;27868:18;;:::i;:::-;27904:2;27897:22;27695:230;;-1:-1:-1;27695:230:1:o;27930:183::-;27990:4;-1:-1:-1;;;;;28015:6:1;28012:30;28009:2;;;28045:18;;:::i;:::-;-1:-1:-1;28090:1:1;28086:14;28102:4;28082:25;;27999:114::o;28118:128::-;28158:3;28189:1;28185:6;28182:1;28179:13;28176:2;;;28195:18;;:::i;:::-;-1:-1:-1;28231:9:1;;28166:80::o;28251:228::-;28290:3;28318:10;28355:2;28352:1;28348:10;28385:2;28382:1;28378:10;28416:3;28412:2;28408:12;28403:3;28400:21;28397:2;;;28424:18;;:::i;:::-;28460:13;;28298:181;-1:-1:-1;;;;28298:181:1:o;28484:236::-;28523:3;-1:-1:-1;;;;;28596:2:1;28593:1;28589:10;28626:2;28623:1;28619:10;28657:3;28653:2;28649:12;28644:3;28641:21;28638:2;;;28665:18;;:::i;28725:204::-;28763:3;28799:4;28796:1;28792:12;28831:4;28828:1;28824:12;28866:3;28860:4;28856:14;28851:3;28848:23;28845:2;;;28874:18;;:::i;:::-;28910:13;;28771:158;-1:-1:-1;;;28771:158:1:o;28934:217::-;28974:1;29000;28990:2;;-1:-1:-1;;;29025:31:1;;29079:4;29076:1;29069:15;29107:4;29032:1;29097:15;28990:2;-1:-1:-1;29136:9:1;;28980:171::o;29156:168::-;29196:7;29262:1;29258;29254:6;29250:14;29247:1;29244:21;29239:1;29232:9;29225:17;29221:45;29218:2;;;29269:18;;:::i;:::-;-1:-1:-1;29309:9:1;;29208:116::o;29329:125::-;29369:4;29397:1;29394;29391:8;29388:2;;;29402:18;;:::i;:::-;-1:-1:-1;29439:9:1;;29378:76::o;29459:258::-;29531:1;29541:113;29555:6;29552:1;29549:13;29541:113;;;29631:11;;;29625:18;29612:11;;;29605:39;29577:2;29570:10;29541:113;;;29672:6;29669:1;29666:13;29663:2;;;29707:1;29698:6;29693:3;29689:16;29682:27;29663:2;;29512:205;;;:::o;29722:135::-;29761:3;-1:-1:-1;;29782:17:1;;29779:2;;;29802:18;;:::i;:::-;-1:-1:-1;29849:1:1;29838:13;;29769:88::o;29862:127::-;29923:10;29918:3;29914:20;29911:1;29904:31;29954:4;29951:1;29944:15;29978:4;29975:1;29968:15;29994:127;30055:10;30050:3;30046:20;30043:1;30036:31;30086:4;30083:1;30076:15;30110:4;30107:1;30100:15
Swarm Source
ipfs://a776ad2c46edd3dd8c68f70e60090b7c22541409e7834950fb98541438769068
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in GLMR
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.