ETH Price: $1,592.56 (-1.46%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
Age
From
To
Finalize Optimis...222828792025-04-16 16:54:1117 mins ago1744822451IN
tBTC: TBTCVault
0 ETH0.000192972.01212711
Request Optimist...222828322025-04-16 16:44:4726 mins ago1744821887IN
tBTC: TBTCVault
0 ETH0.000161572.2901335
Finalize Optimis...222828282025-04-16 16:43:5927 mins ago1744821839IN
tBTC: TBTCVault
0 ETH0.000224912.34520557
Finalize Optimis...222828192025-04-16 16:42:1129 mins ago1744821731IN
tBTC: TBTCVault
0 ETH0.000226722.36463195
Finalize Optimis...222828152025-04-16 16:41:2329 mins ago1744821683IN
tBTC: TBTCVault
0 ETH0.000225062.34668742
Request Optimist...222827052025-04-16 16:18:5952 mins ago1744820339IN
tBTC: TBTCVault
0 ETH0.000143362.0319371
Finalize Optimis...222826992025-04-16 16:17:4753 mins ago1744820267IN
tBTC: TBTCVault
0 ETH0.000195232.03572523
Finalize Optimis...222826982025-04-16 16:17:3553 mins ago1744820255IN
tBTC: TBTCVault
0 ETH0.000197252.05674338
Finalize Optimis...222826972025-04-16 16:17:2353 mins ago1744820243IN
tBTC: TBTCVault
0 ETH0.000193992.02306028
Finalize Optimis...222826942025-04-16 16:16:4754 mins ago1744820207IN
tBTC: TBTCVault
0 ETH0.000198172.06630106
Finalize Optimis...222826942025-04-16 16:16:4754 mins ago1744820207IN
tBTC: TBTCVault
0 ETH0.000198172.06630106
Finalize Optimis...222826862025-04-16 16:15:1156 mins ago1744820111IN
tBTC: TBTCVault
0 ETH0.000190771.98922231
Finalize Optimis...222825832025-04-16 15:54:351 hr ago1744818875IN
tBTC: TBTCVault
0 ETH0.000252022.23045007
Request Optimist...222825252025-04-16 15:42:591 hr ago1744818179IN
tBTC: TBTCVault
0 ETH0.000184432.61411063
Request Optimist...222825032025-04-16 15:38:231 hr ago1744817903IN
tBTC: TBTCVault
0 ETH0.000185852.63506723
Request Optimist...222824922025-04-16 15:36:111 hr ago1744817771IN
tBTC: TBTCVault
0 ETH0.000175282.48438656
Request Optimist...222824812025-04-16 15:33:591 hr ago1744817639IN
tBTC: TBTCVault
0 ETH0.000177652.5180248
Request Optimist...222823872025-04-16 15:15:111 hr ago1744816511IN
tBTC: TBTCVault
0 ETH0.000161852.29400465
Request Optimist...222823852025-04-16 15:14:471 hr ago1744816487IN
tBTC: TBTCVault
0 ETH0.000162072.29752865
Request Optimist...222823832025-04-16 15:14:231 hr ago1744816463IN
tBTC: TBTCVault
0 ETH0.00016352.31742096
Request Optimist...222823762025-04-16 15:12:591 hr ago1744816379IN
tBTC: TBTCVault
0 ETH0.000175522.487849
Request Optimist...222823752025-04-16 15:12:471 hr ago1744816367IN
tBTC: TBTCVault
0 ETH0.000177732.51913635
Request Optimist...222823732025-04-16 15:12:231 hr ago1744816343IN
tBTC: TBTCVault
0 ETH0.000175852.49246691
Finalize Optimis...222823232025-04-16 15:02:232 hrs ago1744815743IN
tBTC: TBTCVault
0 ETH0.000254282.65135895
Request Optimist...222822722025-04-16 14:52:112 hrs ago1744815131IN
tBTC: TBTCVault
0 ETH0.000200312.83971218
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
TBTCVault

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 1000 runs

Other Settings:
default evmVersion
File 1 of 62 : TBTCVault.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: GPL-3.0-only
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
pragma solidity 0.8.17;
import "@openzeppelin/contracts/access/Ownable.sol";
import "./IVault.sol";
import "./TBTCOptimisticMinting.sol";
import "../bank/Bank.sol";
import "../token/TBTC.sol";
/// @title TBTC application vault
/// @notice TBTC is a fully Bitcoin-backed ERC-20 token pegged to the price of
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 2 of 62 : BTCUtils.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
pragma solidity ^0.8.4;
/** @title BitcoinSPV */
/** @author Summa (https://summa.one) */
import {BytesLib} from "./BytesLib.sol";
import {SafeMath} from "./SafeMath.sol";
library BTCUtils {
using BytesLib for bytes;
using SafeMath for uint256;
// The target at minimum Difficulty. Also the target of the genesis block
uint256 public constant DIFF1_TARGET = 0xffff0000000000000000000000000000000000000000000000000000;
uint256 public constant RETARGET_PERIOD = 2 * 7 * 24 * 60 * 60; // 2 weeks in seconds
uint256 public constant RETARGET_PERIOD_BLOCKS = 2016; // 2 weeks in blocks
uint256 public constant ERR_BAD_ARG = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
/* ***** */
/* UTILS */
/* ***** */
/// @notice Determines the length of a VarInt in bytes
/// @dev A VarInt of >1 byte is prefixed with a flag indicating its length
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 3 of 62 : BytesLib.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
pragma solidity ^0.8.4;
/*
https://github.com/GNSPS/solidity-bytes-utils/
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 4 of 62 : CheckBitcoinSigs.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
pragma solidity ^0.8.4;
/** @title CheckBitcoinSigs */
/** @author Summa (https://summa.one) */
import {BytesLib} from "./BytesLib.sol";
import {BTCUtils} from "./BTCUtils.sol";
library CheckBitcoinSigs {
using BytesLib for bytes;
using BTCUtils for bytes;
/// @notice Derives an Ethereum Account address from a pubkey
/// @dev The address is the last 20 bytes of the keccak256 of the address
/// @param _pubkey The public key X & Y. Unprefixed, as a 64-byte array
/// @return The account address
function accountFromPubkey(bytes memory _pubkey) internal pure returns (address) {
require(_pubkey.length == 64, "Pubkey must be 64-byte raw, uncompressed key.");
// keccak hash of uncompressed unprefixed pubkey
bytes32 _digest = keccak256(_pubkey);
return address(uint160(uint256(_digest)));
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 5 of 62 : SafeMath.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
pragma solidity ^0.8.4;
/*
The MIT License (MIT)
Copyright (c) 2016 Smart Contract Solutions, Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 6 of 62 : ValidateSPV.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
pragma solidity ^0.8.4;
/** @title ValidateSPV*/
/** @author Summa (https://summa.one) */
import {BytesLib} from "./BytesLib.sol";
import {SafeMath} from "./SafeMath.sol";
import {BTCUtils} from "./BTCUtils.sol";
library ValidateSPV {
using BTCUtils for bytes;
using BTCUtils for uint256;
using BytesLib for bytes;
using SafeMath for uint256;
enum InputTypes { NONE, LEGACY, COMPATIBILITY, WITNESS }
enum OutputTypes { NONE, WPKH, WSH, OP_RETURN, PKH, SH, NONSTANDARD }
uint256 constant ERR_BAD_LENGTH = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
uint256 constant ERR_INVALID_CHAIN = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe;
uint256 constant ERR_LOW_WORK = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd;
function getErrBadLength() internal pure returns (uint256) {
return ERR_BAD_LENGTH;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 7 of 62 : IWalletOwner.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: GPL-3.0-only
//
// ▓▓▌ ▓▓ ▐▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▄
// ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓ ▓▓▓▓▓▓▓▀ ▐▓▓▓▓▓▓ ▐▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓ ▐▓▓▓▓▓▌ ▐▓▓▓▓▓▓
// ▓▓▓▓▓▓▄▄▓▓▓▓▓▓▓▀ ▐▓▓▓▓▓▓▄▄▄▄ ▓▓▓▓▓▓▄▄▄▄ ▐▓▓▓▓▓▌ ▐▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▓▓▓▓▓▀ ▐▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▀▀▓▓▓▓▓▓▄ ▐▓▓▓▓▓▓▀▀▀▀ ▓▓▓▓▓▓▀▀▀▀ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▀
// ▓▓▓▓▓▓ ▀▓▓▓▓▓▓▄ ▐▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓ ▐▓▓▓▓▓▌
// ▓▓▓▓▓▓▓▓▓▓ █▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓
//
// Trust math, not hardware.
pragma solidity 0.8.17;
interface IWalletOwner {
/// @notice Callback function executed once a new wallet is created.
/// @dev Should be callable only by the Wallet Registry.
/// @param walletID Wallet's unique identifier.
/// @param publicKeyY Wallet's public key's X coordinate.
/// @param publicKeyY Wallet's public key's Y coordinate.
function __ecdsaWalletCreatedCallback(
bytes32 walletID,
bytes32 publicKeyX,
bytes32 publicKeyY
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 8 of 62 : IWalletRegistry.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: GPL-3.0-only
//
// ▓▓▌ ▓▓ ▐▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▄
// ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓ ▓▓▓▓▓▓▓▀ ▐▓▓▓▓▓▓ ▐▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓ ▐▓▓▓▓▓▌ ▐▓▓▓▓▓▓
// ▓▓▓▓▓▓▄▄▓▓▓▓▓▓▓▀ ▐▓▓▓▓▓▓▄▄▄▄ ▓▓▓▓▓▓▄▄▄▄ ▐▓▓▓▓▓▌ ▐▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▓▓▓▓▓▀ ▐▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▀▀▓▓▓▓▓▓▄ ▐▓▓▓▓▓▓▀▀▀▀ ▓▓▓▓▓▓▀▀▀▀ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▀
// ▓▓▓▓▓▓ ▀▓▓▓▓▓▓▄ ▐▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓ ▐▓▓▓▓▓▌
// ▓▓▓▓▓▓▓▓▓▓ █▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓
//
// Trust math, not hardware.
pragma solidity 0.8.17;
import "../libraries/EcdsaDkg.sol";
interface IWalletRegistry {
/// @notice Requests a new wallet creation.
/// @dev Only the Wallet Owner can call this function.
function requestNewWallet() external;
/// @notice Closes an existing wallet.
/// @param walletID ID of the wallet.
/// @dev Only the Wallet Owner can call this function.
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 9 of 62 : EcdsaDkgValidator.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: GPL-3.0-only
//
// ▓▓▌ ▓▓ ▐▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▄
// ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓ ▓▓▓▓▓▓▓▀ ▐▓▓▓▓▓▓ ▐▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓ ▐▓▓▓▓▓▌ ▐▓▓▓▓▓▓
// ▓▓▓▓▓▓▄▄▓▓▓▓▓▓▓▀ ▐▓▓▓▓▓▓▄▄▄▄ ▓▓▓▓▓▓▄▄▄▄ ▐▓▓▓▓▓▌ ▐▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▓▓▓▓▓▀ ▐▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▀▀▓▓▓▓▓▓▄ ▐▓▓▓▓▓▓▀▀▀▀ ▓▓▓▓▓▓▀▀▀▀ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▀
// ▓▓▓▓▓▓ ▀▓▓▓▓▓▓▄ ▐▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓ ▐▓▓▓▓▓▌
// ▓▓▓▓▓▓▓▓▓▓ █▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓
//
// Trust math, not hardware.
// Initial version copied from Keep Network Random Beacon:
// https://github.com/keep-network/keep-core/blob/5138c7628868dbeed3ae2164f76fccc6c1fbb9e8/solidity/random-beacon/contracts/DKGValidator.sol
//
// With the following differences:
// - group public key length,
// - group size and related thresholds,
// - documentation.
pragma solidity 0.8.17;
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "@keep-network/random-beacon/contracts/libraries/BytesLib.sol";
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 10 of 62 : EcdsaDkg.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: GPL-3.0-only
//
// ▓▓▌ ▓▓ ▐▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▄
// ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓ ▓▓▓▓▓▓▓▀ ▐▓▓▓▓▓▓ ▐▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓ ▐▓▓▓▓▓▌ ▐▓▓▓▓▓▓
// ▓▓▓▓▓▓▄▄▓▓▓▓▓▓▓▀ ▐▓▓▓▓▓▓▄▄▄▄ ▓▓▓▓▓▓▄▄▄▄ ▐▓▓▓▓▓▌ ▐▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▓▓▓▓▓▀ ▐▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▀▀▓▓▓▓▓▓▄ ▐▓▓▓▓▓▓▀▀▀▀ ▓▓▓▓▓▓▀▀▀▀ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▀
// ▓▓▓▓▓▓ ▀▓▓▓▓▓▓▄ ▐▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓ ▐▓▓▓▓▓▌
// ▓▓▓▓▓▓▓▓▓▓ █▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓
//
//
// Initial version copied from Keep Network Random Beacon:
// https://github.com/keep-network/keep-core/blob/5138c7628868dbeed3ae2164f76fccc6c1fbb9e8/solidity/random-beacon/contracts/libraries/DKG.sol
//
// With the following differences:
// - the group size was set to 100,
// - offchainDkgTimeout was removed,
// - submission eligibility verification is not performed on-chain,
// - submission eligibility delay was replaced with a submission timeout,
// - seed timeout notification requires seedTimeout period to pass.
pragma solidity 0.8.17;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 11 of 62 : Governable.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: GPL-3.0-only
//
// ▓▓▌ ▓▓ ▐▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▄
// ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓ ▓▓▓▓▓▓▓▀ ▐▓▓▓▓▓▓ ▐▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓ ▐▓▓▓▓▓▌ ▐▓▓▓▓▓▓
// ▓▓▓▓▓▓▄▄▓▓▓▓▓▓▓▀ ▐▓▓▓▓▓▓▄▄▄▄ ▓▓▓▓▓▓▄▄▄▄ ▐▓▓▓▓▓▌ ▐▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▓▓▓▓▓▀ ▐▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▀▀▓▓▓▓▓▓▄ ▐▓▓▓▓▓▓▀▀▀▀ ▓▓▓▓▓▓▀▀▀▀ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▀
// ▓▓▓▓▓▓ ▀▓▓▓▓▓▓▄ ▐▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓ ▐▓▓▓▓▓▌
// ▓▓▓▓▓▓▓▓▓▓ █▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓
//
// Trust math, not hardware.
pragma solidity 0.8.17;
/// @notice Governable contract.
/// @dev A constructor is not defined, which makes the contract compatible with
/// upgradable proxies. This requires calling explicitly `_transferGovernance`
/// function in a child contract.
abstract contract Governable {
// Governance of the contract
// The variable should be initialized by the implementing contract.
// slither-disable-next-line uninitialized-state
address public governance;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 12 of 62 : BytesLib.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: GPL-3.0-only
//
// ▓▓▌ ▓▓ ▐▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▄
// ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓ ▓▓▓▓▓▓▓▀ ▐▓▓▓▓▓▓ ▐▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓ ▐▓▓▓▓▓▌ ▐▓▓▓▓▓▓
// ▓▓▓▓▓▓▄▄▓▓▓▓▓▓▓▀ ▐▓▓▓▓▓▓▄▄▄▄ ▓▓▓▓▓▓▄▄▄▄ ▐▓▓▓▓▓▌ ▐▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▓▓▓▓▓▀ ▐▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▀▀▓▓▓▓▓▓▄ ▐▓▓▓▓▓▓▀▀▀▀ ▓▓▓▓▓▓▀▀▀▀ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▀
// ▓▓▓▓▓▓ ▀▓▓▓▓▓▓▄ ▐▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓ ▐▓▓▓▓▓▌
// ▓▓▓▓▓▓▓▓▓▓ █▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓
//
//
pragma solidity 0.8.17;
/*
Version pulled from keep-core v1:
https://github.com/keep-network/keep-core/blob/f297202db00c027978ad8e7103a356503de5773c/solidity-v1/contracts/utils/BytesLib.sol
To compile it with solidity 0.8 `_preBytes_slot` was replaced with `_preBytes.slot`.
*/
/*
https://github.com/GNSPS/solidity-bytes-utils/
This is free and unencumbered software released into the public domain.
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 13 of 62 : ReimbursementPool.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: GPL-3.0-only
//
// ▓▓▌ ▓▓ ▐▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▄
// ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓ ▓▓▓▓▓▓▓▀ ▐▓▓▓▓▓▓ ▐▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓ ▐▓▓▓▓▓▌ ▐▓▓▓▓▓▓
// ▓▓▓▓▓▓▄▄▓▓▓▓▓▓▓▀ ▐▓▓▓▓▓▓▄▄▄▄ ▓▓▓▓▓▓▄▄▄▄ ▐▓▓▓▓▓▌ ▐▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▓▓▓▓▓▀ ▐▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▀▀▓▓▓▓▓▓▄ ▐▓▓▓▓▓▓▀▀▀▀ ▓▓▓▓▓▓▀▀▀▀ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▀
// ▓▓▓▓▓▓ ▀▓▓▓▓▓▓▄ ▐▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓ ▐▓▓▓▓▓▌
// ▓▓▓▓▓▓▓▓▓▓ █▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓
//
// Trust math, not hardware.
pragma solidity 0.8.17;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
contract ReimbursementPool is Ownable, ReentrancyGuard {
/// @notice Authorized contracts that can interact with the reimbursment pool.
/// Authorization can be granted and removed by the owner.
mapping(address => bool) public isAuthorized;
/// @notice Static gas includes:
/// - cost of the refund function
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 14 of 62 : Branch.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
pragma solidity 0.8.17;
import "./Constants.sol";
/// @notice The implicit 8-ary trees of the sortition pool
/// rely on packing 8 "slots" of 32-bit values into each uint256.
/// The Branch library permits efficient calculations on these slots.
library Branch {
/// @notice Calculate the right shift required
/// to make the 32 least significant bits of an uint256
/// be the bits of the `position`th slot
/// when treating the uint256 as a uint32[8].
///
/// @dev Not used for efficiency reasons,
/// but left to illustrate the meaning of a common pattern.
/// I wish solidity had macros, even C macros.
function slotShift(uint256 position) internal pure returns (uint256) {
unchecked {
return position * Constants.SLOT_WIDTH;
}
}
/// @notice Return the `position`th slot of the `node`,
/// treating `node` as a uint32[32].
function getSlot(uint256 node, uint256 position)
internal
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 15 of 62 : Chaosnet.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
pragma solidity 0.8.17;
/// @title Chaosnet
/// @notice This is a beta staker program for stakers willing to go the extra
/// mile with monitoring, share their logs with the dev team, and allow to more
/// carefully monitor the bootstrapping network. As the network matures, the
/// beta program will be ended.
contract Chaosnet {
/// @notice Indicates if the chaosnet is active. The chaosnet is active
/// after the contract deployment and can be ended with a call to
/// `deactivateChaosnet()`. Once deactivated chaosnet can not be activated
/// again.
bool public isChaosnetActive;
/// @notice Indicates if the given operator is a beta operator for chaosnet.
mapping(address => bool) public isBetaOperator;
/// @notice Address controlling chaosnet status and beta operator addresses.
address public chaosnetOwner;
event BetaOperatorsAdded(address[] operators);
event ChaosnetOwnerRoleTransferred(
address oldChaosnetOwner,
address newChaosnetOwner
);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 16 of 62 : Constants.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
pragma solidity 0.8.17;
library Constants {
////////////////////////////////////////////////////////////////////////////
// Parameters for configuration
// How many bits a position uses per level of the tree;
// each branch of the tree contains 2**SLOT_BITS slots.
uint256 constant SLOT_BITS = 3;
uint256 constant LEVELS = 7;
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// Derived constants, do not touch
uint256 constant SLOT_COUNT = 2**SLOT_BITS;
uint256 constant SLOT_WIDTH = 256 / SLOT_COUNT;
uint256 constant LAST_SLOT = SLOT_COUNT - 1;
uint256 constant SLOT_MAX = (2**SLOT_WIDTH) - 1;
uint256 constant POOL_CAPACITY = SLOT_COUNT**LEVELS;
uint256 constant ID_WIDTH = SLOT_WIDTH;
uint256 constant ID_MAX = SLOT_MAX;
uint256 constant BLOCKHEIGHT_WIDTH = 96 - ID_WIDTH;
uint256 constant BLOCKHEIGHT_MAX = (2**BLOCKHEIGHT_WIDTH) - 1;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 17 of 62 : Leaf.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
pragma solidity 0.8.17;
import "./Constants.sol";
library Leaf {
function make(
address _operator,
uint256 _creationBlock,
uint256 _id
) internal pure returns (uint256) {
assert(_creationBlock <= type(uint64).max);
assert(_id <= type(uint32).max);
// Converting a bytesX type into a larger type
// adds zero bytes on the right.
uint256 op = uint256(bytes32(bytes20(_operator)));
// Bitwise AND the id to erase
// all but the 32 least significant bits
uint256 uid = _id & Constants.ID_MAX;
// Erase all but the 64 least significant bits,
// then shift left by 32 bits to make room for the id
uint256 cb = (_creationBlock & Constants.BLOCKHEIGHT_MAX) <<
Constants.ID_WIDTH;
// Bitwise OR them all together to get
// [address operator || uint64 creationBlock || uint32 id]
return (op | cb | uid);
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 18 of 62 : Position.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
pragma solidity 0.8.17;
import "./Constants.sol";
library Position {
// Return the last 3 bits of a position number,
// corresponding to its slot in its parent
function slot(uint256 a) internal pure returns (uint256) {
return a & Constants.SLOT_POINTER_MAX;
}
// Return the parent of a position number
function parent(uint256 a) internal pure returns (uint256) {
return a >> Constants.SLOT_BITS;
}
// Return the location of the child of a at the given slot
function child(uint256 a, uint256 s) internal pure returns (uint256) {
return (a << Constants.SLOT_BITS) | (s & Constants.SLOT_POINTER_MAX); // slot(s)
}
// Return the uint p as a flagged position uint:
// the least significant 21 bits contain the position
// and the 22nd bit is set as a flag
// to distinguish the position 0x000000 from an empty field.
function setFlag(uint256 p) internal pure returns (uint256) {
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 19 of 62 : Rewards.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
pragma solidity 0.8.17;
/// @title Rewards
/// @notice Rewards are allocated proportionally to operators
/// present in the pool at payout based on their weight in the pool.
///
/// To facilitate this, we use a global accumulator value
/// to track the total rewards one unit of weight would've earned
/// since the creation of the pool.
///
/// Whenever a reward is paid, the accumulator is increased
/// by the size of the reward divided by the total weight
/// of all eligible operators in the pool.
///
/// Each operator has an individual accumulator value,
/// set to equal the global accumulator when the operator joins the pool.
/// This accumulator reflects the amount of rewards
/// that have already been accounted for with that operator.
///
/// Whenever an operator's weight in the pool changes,
/// we can update the amount of rewards the operator has earned
/// by subtracting the operator's accumulator from the global accumulator.
/// This gives us the amount of rewards one unit of weight has earned
/// since the last time the operator's rewards have been updated.
/// Then we multiply that by the operator's previous (pre-change) weight
/// to determine how much rewards in total the operator has earned,
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 20 of 62 : RNG.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
pragma solidity 0.8.17;
import "./Leaf.sol";
import "./Constants.sol";
library RNG {
/// @notice Get an index in the range `[0 .. range-1]`
/// and the new state of the RNG,
/// using the provided `state` of the RNG.
///
/// @param range The upper bound of the index, exclusive.
///
/// @param state The previous state of the RNG.
/// The initial state needs to be obtained
/// from a trusted randomness oracle (the random beacon),
/// or from a chain of earlier calls to `RNG.getIndex()`
/// on an originally trusted seed.
///
/// @dev Calculates the number of bits required for the desired range,
/// takes the least significant bits of `state`
/// and checks if the obtained index is within the desired range.
/// The original state is hashed with `keccak256` to get a new state.
/// If the index is outside the range,
/// the function retries until it gets a suitable index.
///
/// @return index A random integer between `0` and `range - 1`, inclusive.
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 21 of 62 : SortitionPool.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
pragma solidity 0.8.17;
import "@thesis/solidity-contracts/contracts/token/IERC20WithPermit.sol";
import "@thesis/solidity-contracts/contracts/token/IReceiveApproval.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./RNG.sol";
import "./SortitionTree.sol";
import "./Rewards.sol";
import "./Chaosnet.sol";
/// @title Sortition Pool
/// @notice A logarithmic data structure used to store the pool of eligible
/// operators weighted by their stakes. It allows to select a group of operators
/// based on the provided pseudo-random seed.
contract SortitionPool is
SortitionTree,
Rewards,
Ownable,
Chaosnet,
IReceiveApproval
{
using Branch for uint256;
using Leaf for uint256;
using Position for uint256;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 22 of 62 : SortitionTree.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
pragma solidity 0.8.17;
import "./Branch.sol";
import "./Position.sol";
import "./Leaf.sol";
import "./Constants.sol";
contract SortitionTree {
using Branch for uint256;
using Position for uint256;
using Leaf for uint256;
// implicit tree
// root 8
// level2 64
// level3 512
// level4 4k
// level5 32k
// level6 256k
// level7 2M
uint256 internal root;
// A 2-index mapping from layer => (index (0-index) => branch). For example,
// to access the 6th branch in the 2nd layer (right below the root node; the
// first branch layer), call branches[2][5]. Mappings are used in place of
// arrays for efficiency. The root is the first layer, the branches occupy
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 23 of 62 : Initializable.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.2;
import "../../utils/AddressUpgradeable.sol";
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 24 of 62 : AddressUpgradeable.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library AddressUpgradeable {
/**
* @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
* ====
*
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 25 of 62 : ECDSAUpgradeable.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/ECDSA.sol)
pragma solidity ^0.8.0;
import "../StringsUpgradeable.sol";
/**
* @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
*
* These functions can be used to verify that a message was signed by the holder
* of the private keys of a given address.
*/
library ECDSAUpgradeable {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS,
InvalidSignatureV
}
function _throwError(RecoverError error) private pure {
if (error == RecoverError.NoError) {
return; // no error: do nothing
} else if (error == RecoverError.InvalidSignature) {
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 26 of 62 : SafeCastUpgradeable.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/math/SafeCast.sol)
pragma solidity ^0.8.0;
/**
* @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
* checks.
*
* Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
* easily result in undesired exploitation or bugs, since developers usually
* assume that overflows raise errors. `SafeCast` restores this intuition by
* reverting the transaction when such an operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*
* Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
* all math on `uint256` and `int256` and then downcasting.
*/
library SafeCastUpgradeable {
/**
* @dev Returns the downcasted uint224 from uint256, reverting on
* overflow (when the input is greater than largest uint224).
*
* Counterpart to Solidity's `uint224` operator.
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 27 of 62 : StringsUpgradeable.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)
pragma solidity ^0.8.0;
/**
* @dev String operations.
*/
library StringsUpgradeable {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
// Inspired by OraclizeAPI's implementation - MIT licence
// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 28 of 62 : Ownable.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 29 of 62 : ReentrancyGuard.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 30 of 62 : IERC20Metadata.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 31 of 62 : IERC20.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 32 of 62 : SafeERC20.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 33 of 62 : IERC721.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC721 compliant contract.
*/
interface IERC721 is IERC165 {
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 34 of 62 : Address.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @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
* ====
*
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 35 of 62 : Context.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 36 of 62 : ECDSA.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/ECDSA.sol)
pragma solidity ^0.8.0;
import "../Strings.sol";
/**
* @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
*
* These functions can be used to verify that a message was signed by the holder
* of the private keys of a given address.
*/
library ECDSA {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS,
InvalidSignatureV
}
function _throwError(RecoverError error) private pure {
if (error == RecoverError.NoError) {
return; // no error: do nothing
} else if (error == RecoverError.InvalidSignature) {
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 37 of 62 : IERC165.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 38 of 62 : Math.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a >= b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 39 of 62 : Strings.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)
pragma solidity ^0.8.0;
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
// Inspired by OraclizeAPI's implementation - MIT licence
// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 40 of 62 : ERC20WithPermit.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/access/Ownable.sol";
import "./IERC20WithPermit.sol";
import "./IReceiveApproval.sol";
/// @title ERC20WithPermit
/// @notice Burnable ERC20 token with EIP2612 permit functionality. User can
/// authorize a transfer of their token with a signature conforming
/// EIP712 standard instead of an on-chain transaction from their
/// address. Anyone can submit this signature on the user's behalf by
/// calling the permit function, as specified in EIP2612 standard,
/// paying gas fees, and possibly performing other actions in the same
/// transaction.
contract ERC20WithPermit is IERC20WithPermit, Ownable {
/// @notice The amount of tokens owned by the given account.
mapping(address => uint256) public override balanceOf;
/// @notice The remaining number of tokens that spender will be
/// allowed to spend on behalf of owner through `transferFrom` and
/// `burnFrom`. This is zero by default.
mapping(address => mapping(address => uint256)) public override allowance;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 41 of 62 : IApproveAndCall.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
/// @notice An interface that should be implemented by tokens supporting
/// `approveAndCall`/`receiveApproval` pattern.
interface IApproveAndCall {
/// @notice Executes `receiveApproval` function on spender as specified in
/// `IReceiveApproval` interface. Approves spender to withdraw from
/// the caller multiple times, up to the `amount`. If this
/// function is called again, it overwrites the current allowance
/// with `amount`. Reverts if the approval reverted or if
/// `receiveApproval` call on the spender reverted.
function approveAndCall(
address spender,
uint256 amount,
bytes memory extraData
) external returns (bool);
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 42 of 62 : IERC20WithPermit.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import "./IApproveAndCall.sol";
/// @title IERC20WithPermit
/// @notice Burnable ERC20 token with EIP2612 permit functionality. User can
/// authorize a transfer of their token with a signature conforming
/// EIP712 standard instead of an on-chain transaction from their
/// address. Anyone can submit this signature on the user's behalf by
/// calling the permit function, as specified in EIP2612 standard,
/// paying gas fees, and possibly performing other actions in the same
/// transaction.
interface IERC20WithPermit is IERC20, IERC20Metadata, IApproveAndCall {
/// @notice EIP2612 approval made with secp256k1 signature.
/// Users can authorize a transfer of their tokens with a signature
/// conforming EIP712 standard, rather than an on-chain transaction
/// from their address. Anyone can submit this signature on the
/// user's behalf by calling the permit function, paying gas fees,
/// and possibly performing other actions in the same transaction.
/// @dev The deadline argument can be set to `type(uint256).max to create
/// permits that effectively never expire.
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 43 of 62 : IReceiveApproval.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
/// @notice An interface that should be implemented by contracts supporting
/// `approveAndCall`/`receiveApproval` pattern.
interface IReceiveApproval {
/// @notice Receives approval to spend tokens. Called as a result of
/// `approveAndCall` call on the token.
function receiveApproval(
address from,
uint256 amount,
address token,
bytes calldata extraData
) external;
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 44 of 62 : MisfundRecovery.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
/// @title MisfundRecovery
/// @notice Allows the owner of the token contract extending MisfundRecovery
/// to recover any ERC20 and ERC721 sent mistakenly to the token
/// contract address.
contract MisfundRecovery is Ownable {
using SafeERC20 for IERC20;
function recoverERC20(
IERC20 token,
address recipient,
uint256 amount
) external onlyOwner {
token.safeTransfer(recipient, amount);
}
function recoverERC721(
IERC721 token,
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 45 of 62 : Bank.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: GPL-3.0-only
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
pragma solidity 0.8.17;
import "@openzeppelin/contracts/access/Ownable.sol";
import "./IReceiveBalanceApproval.sol";
import "../vault/IVault.sol";
/// @title Bitcoin Bank
/// @notice Bank is a central component tracking Bitcoin balances. Balances can
/// be transferred between balance owners, and balance owners can
/// approve their balances to be spent by others. Balances in the Bank
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 46 of 62 : IReceiveBalanceApproval.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: GPL-3.0-only
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
pragma solidity 0.8.17;
/// @title IReceiveBalanceApproval
/// @notice `IReceiveBalanceApproval` is an interface for a smart contract
/// consuming Bank balances approved to them in the same transaction by
/// other contracts or externally owned accounts (EOA).
interface IReceiveBalanceApproval {
/// @notice Called by the Bank in `approveBalanceAndCall` function after
/// the balance `owner` approved `amount` of their balance in the
/// Bank for the contract. This way, the depositor can approve
/// balance and call the contract to use the approved balance in
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 47 of 62 : BitcoinTx.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: GPL-3.0-only
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
pragma solidity 0.8.17;
import {BTCUtils} from "@keep-network/bitcoin-spv-sol/contracts/BTCUtils.sol";
import {BytesLib} from "@keep-network/bitcoin-spv-sol/contracts/BytesLib.sol";
import {ValidateSPV} from "@keep-network/bitcoin-spv-sol/contracts/ValidateSPV.sol";
import "./BridgeState.sol";
/// @title Bitcoin transaction
/// @notice Allows to reference Bitcoin raw transaction in Solidity.
/// @dev See https://developer.bitcoin.org/reference/transactions.html#raw-transaction-format
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 48 of 62 : Bridge.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: GPL-3.0-only
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
pragma solidity 0.8.17;
import "@keep-network/random-beacon/contracts/Governable.sol";
import "@keep-network/random-beacon/contracts/ReimbursementPool.sol";
import {IWalletOwner as EcdsaWalletOwner} from "@keep-network/ecdsa/contracts/api/IWalletOwner.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol";
import "./IRelay.sol";
import "./BridgeState.sol";
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 49 of 62 : BridgeState.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: GPL-3.0-only
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
pragma solidity 0.8.17;
import {IWalletRegistry as EcdsaWalletRegistry} from "@keep-network/ecdsa/contracts/api/IWalletRegistry.sol";
import "@keep-network/random-beacon/contracts/ReimbursementPool.sol";
import "./IRelay.sol";
import "./Deposit.sol";
import "./Redemption.sol";
import "./Fraud.sol";
import "./Wallets.sol";
import "./MovingFunds.sol";
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 50 of 62 : Deposit.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: GPL-3.0-only
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
pragma solidity 0.8.17;
import {BTCUtils} from "@keep-network/bitcoin-spv-sol/contracts/BTCUtils.sol";
import {BytesLib} from "@keep-network/bitcoin-spv-sol/contracts/BytesLib.sol";
import "./BitcoinTx.sol";
import "./BridgeState.sol";
import "./Wallets.sol";
/// @title Bridge deposit
/// @notice The library handles the logic for revealing Bitcoin deposits to
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 51 of 62 : DepositSweep.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: GPL-3.0-only
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
pragma solidity 0.8.17;
import {BTCUtils} from "@keep-network/bitcoin-spv-sol/contracts/BTCUtils.sol";
import "./BitcoinTx.sol";
import "./BridgeState.sol";
import "./Wallets.sol";
import "../bank/Bank.sol";
/// @title Bridge deposit sweep
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 52 of 62 : EcdsaLib.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: GPL-3.0-only
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
pragma solidity 0.8.17;
import "@keep-network/bitcoin-spv-sol/contracts/BytesLib.sol";
library EcdsaLib {
using BytesLib for bytes;
/// @notice Converts public key X and Y coordinates (32-byte each) to a
/// compressed public key (33-byte). Compressed public key is X
/// coordinate prefixed with `02` or `03` based on the Y coordinate parity.
/// It is expected that the uncompressed public key is stripped
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 53 of 62 : Fraud.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: GPL-3.0-only
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
pragma solidity 0.8.17;
import {BytesLib} from "@keep-network/bitcoin-spv-sol/contracts/BytesLib.sol";
import {BTCUtils} from "@keep-network/bitcoin-spv-sol/contracts/BTCUtils.sol";
import {CheckBitcoinSigs} from "@keep-network/bitcoin-spv-sol/contracts/CheckBitcoinSigs.sol";
import "./BitcoinTx.sol";
import "./EcdsaLib.sol";
import "./BridgeState.sol";
import "./Heartbeat.sol";
import "./MovingFunds.sol";
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 54 of 62 : Heartbeat.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: GPL-3.0-only
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
pragma solidity 0.8.17;
import {BytesLib} from "@keep-network/bitcoin-spv-sol/contracts/BytesLib.sol";
/// @title Bridge wallet heartbeat
/// @notice The library establishes expected format for heartbeat messages
/// signed by wallet ECDSA signing group. Heartbeat messages are
/// constructed in such a way that they can not be used as a Bitcoin
/// transaction preimages.
/// @dev The smallest Bitcoin non-coinbase transaction is a one spending an
/// OP_TRUE anyonecanspend output and creating 1 OP_TRUE anyonecanspend
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 55 of 62 : IRelay.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: GPL-3.0-only
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
pragma solidity 0.8.17;
/// @title Interface for the Bitcoin relay
/// @notice Contains only the methods needed by tBTC v2. The Bitcoin relay
/// provides the difficulty of the previous and current epoch. One
/// difficulty epoch spans 2016 blocks.
interface IRelay {
/// @notice Returns the difficulty of the current epoch.
function getCurrentEpochDifficulty() external view returns (uint256);
/// @notice Returns the difficulty of the previous epoch.
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 56 of 62 : MovingFunds.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: GPL-3.0-only
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
pragma solidity 0.8.17;
import {BTCUtils} from "@keep-network/bitcoin-spv-sol/contracts/BTCUtils.sol";
import {BytesLib} from "@keep-network/bitcoin-spv-sol/contracts/BytesLib.sol";
import "./BitcoinTx.sol";
import "./BridgeState.sol";
import "./Redemption.sol";
import "./Wallets.sol";
/// @title Moving Bridge wallet funds
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 57 of 62 : Redemption.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: GPL-3.0-only
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
pragma solidity 0.8.17;
import {BTCUtils} from "@keep-network/bitcoin-spv-sol/contracts/BTCUtils.sol";
import {BytesLib} from "@keep-network/bitcoin-spv-sol/contracts/BytesLib.sol";
import "./BitcoinTx.sol";
import "./BridgeState.sol";
import "./Wallets.sol";
import "../bank/Bank.sol";
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 58 of 62 : Wallets.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: GPL-3.0-only
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
pragma solidity 0.8.17;
import {BTCUtils} from "@keep-network/bitcoin-spv-sol/contracts/BTCUtils.sol";
import {EcdsaDkg} from "@keep-network/ecdsa/contracts/libraries/EcdsaDkg.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import "./BitcoinTx.sol";
import "./EcdsaLib.sol";
import "./BridgeState.sol";
/// @title Wallet library
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 59 of 62 : GovernanceUtils.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.17;
library GovernanceUtils {
/// @notice Reverts if the governance delay has not passed since
/// the change initiated time or if the change has not been
/// initiated.
/// @param changeInitiatedTimestamp The timestamp at which the change has
/// been initiated.
/// @param delay Governance delay.
function onlyAfterGovernanceDelay(
uint256 changeInitiatedTimestamp,
uint256 delay
) internal view {
require(changeInitiatedTimestamp > 0, "Change not initiated");
require(
/* solhint-disable-next-line not-rely-on-time */
block.timestamp - changeInitiatedTimestamp >= delay,
"Governance delay has not elapsed"
);
}
/// @notice Gets the time remaining until the governable parameter update
/// can be committed.
/// @param changeInitiatedTimestamp Timestamp indicating the beginning of
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 60 of 62 : TBTC.sol
1
2
3
4
5
6
7
8
9
10
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.17;
import "@thesis/solidity-contracts/contracts/token/ERC20WithPermit.sol";
import "@thesis/solidity-contracts/contracts/token/MisfundRecovery.sol";
contract TBTC is ERC20WithPermit, MisfundRecovery {
constructor() ERC20WithPermit("tBTC v2", "tBTC") {}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 61 of 62 : IVault.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: GPL-3.0-only
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
pragma solidity 0.8.17;
import "../bank/IReceiveBalanceApproval.sol";
/// @title Bank Vault interface
/// @notice `IVault` is an interface for a smart contract consuming Bank
/// balances of other contracts or externally owned accounts (EOA).
interface IVault is IReceiveBalanceApproval {
/// @notice Called by the Bank in `increaseBalanceAndCall` function after
/// increasing the balance in the Bank for the vault. It happens in
/// the same transaction in which deposits were swept by the Bridge.
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File 62 of 62 : TBTCOptimisticMinting.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// SPDX-License-Identifier: GPL-3.0-only
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
pragma solidity 0.8.17;
import "../bridge/Bridge.sol";
import "../bridge/Deposit.sol";
import "../GovernanceUtils.sol";
/// @title TBTC Optimistic Minting
/// @notice The Optimistic Minting mechanism allows to mint TBTC before
/// `TBTCVault` receives the Bank balance. There are two permissioned
/// sets in the system: Minters and Guardians, both set up in 1-of-n
/// mode. Minters observe the revealed deposits and request minting TBTC.
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Settings
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"optimizer": {
"enabled": true,
"runs": 1000
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"metadata": {
"useLiteralContent": true
},
"libraries": {}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"contract Bank","name":"_bank","type":"address"},{"internalType":"contract TBTC","name":"_tbtcToken","type":"address"},{"internalType":"contract Bridge","name":"_bridge","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"guardian","type":"address"}],"name":"GuardianAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"guardian","type":"address"}],"name":"GuardianRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Minted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"}],"name":"MinterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"}],"name":"MinterRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"guardian","type":"address"},{"indexed":true,"internalType":"uint256","name":"depositKey","type":"uint256"}],"name":"OptimisticMintingCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"depositor","type":"address"},{"indexed":false,"internalType":"uint256","name":"optimisticMintingDebt","type":"uint256"}],"name":"OptimisticMintingDebtRepaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"newOptimisticMintingDelay","type":"uint32"}],"name":"OptimisticMintingDelayUpdateStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"newOptimisticMintingDelay","type":"uint32"}],"name":"OptimisticMintingDelayUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"newOptimisticMintingFeeDivisor","type":"uint32"}],"name":"OptimisticMintingFeeUpdateStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"newOptimisticMintingFeeDivisor","type":"uint32"}],"name":"OptimisticMintingFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"},{"indexed":true,"internalType":"uint256","name":"depositKey","type":"uint256"},{"indexed":true,"internalType":"address","name":"depositor","type":"address"},{"indexed":false,"internalType":"uint256","name":"optimisticMintingDebt","type":"uint256"}],"name":"OptimisticMintingFinalized","type":"event"},{"anonymous":false,"inputs":[],"name":"OptimisticMintingPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"},{"indexed":true,"internalType":"uint256","name":"depositKey","type":"uint256"},{"indexed":true,"internalType":"address","name":"depositor","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"fundingTxHash","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"fundingOutputIndex","type":"uint32"}],"name":"OptimisticMintingRequested","type":"event"},{"anonymous":false,"inputs":[],"name":"OptimisticMintingUnpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Unminted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newVault","type":"address"}],"name":"UpgradeFinalized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newVault","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"UpgradeInitiated","type":"event"},{"inputs":[],"name":"GOVERNANCE_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SATOSHI_MULTIPLIER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"}],"name":"addGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"addMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"amountToSatoshis","outputs":[{"internalType":"uint256","name":"convertibleAmount","type":"uint256"},{"internalType":"uint256","name":"remainder","type":"uint256"},{"internalType":"uint256","name":"satoshis","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bank","outputs":[{"internalType":"contract Bank","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_newOptimisticMintingDelay","type":"uint32"}],"name":"beginOptimisticMintingDelayUpdate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_newOptimisticMintingFeeDivisor","type":"uint32"}],"name":"beginOptimisticMintingFeeUpdate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"bridge","outputs":[{"internalType":"contract Bridge","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"fundingTxHash","type":"bytes32"},{"internalType":"uint32","name":"fundingOutputIndex","type":"uint32"}],"name":"calculateDepositKey","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"fundingTxHash","type":"bytes32"},{"internalType":"uint32","name":"fundingOutputIndex","type":"uint32"}],"name":"cancelOptimisticMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"fundingTxHash","type":"bytes32"},{"internalType":"uint32","name":"fundingOutputIndex","type":"uint32"}],"name":"finalizeOptimisticMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"finalizeOptimisticMintingDelayUpdate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"finalizeOptimisticMintingFeeUpdate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"finalizeUpgrade","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getMinters","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newVault","type":"address"}],"name":"initiateUpgrade","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isGuardian","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isOptimisticMintingPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"minters","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"newOptimisticMintingDelay","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"newOptimisticMintingFeeDivisor","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"newVault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"optimisticMintingDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"optimisticMintingDelay","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"optimisticMintingDelayUpdateInitiatedTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"optimisticMintingFeeDivisor","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"optimisticMintingFeeUpdateInitiatedTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"optimisticMintingRequests","outputs":[{"internalType":"uint64","name":"requestedAt","type":"uint64"},{"internalType":"uint64","name":"finalizedAt","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauseOptimisticMinting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"receiveApproval","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"satoshis","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"receiveBalanceApproval","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"depositors","type":"address[]"},{"internalType":"uint256[]","name":"depositedSatoshiAmounts","type":"uint256[]"}],"name":"receiveBalanceIncrease","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"recoverERC20FromToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC721","name":"token","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"recoverERC721","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC721","name":"token","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"recoverERC721FromToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"}],"name":"removeGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"removeMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"fundingTxHash","type":"bytes32"},{"internalType":"uint32","name":"fundingOutputIndex","type":"uint32"}],"name":"requestOptimisticMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tbtcToken","outputs":[{"internalType":"contract TBTC","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"unmint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"redemptionData","type":"bytes"}],"name":"unmintAndRedeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpauseOptimisticMinting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"upgradeInitiatedTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

60e060405260008054600160a81b600160e81b031916650a8c0000007d60aa1b1790553480156200002f57600080fd5b5060405162003e2f38038062003e2f83398101604081905262000052916200020c565b806200005e33620001a3565b6001600160a01b038116620000c55760405162461bcd60e51b815260206004820152602260248201527f4272696467652063616e206e6f7420626520746865207a65726f206164647265604482015261737360f01b60648201526084015b60405180910390fd5b6001600160a01b039081166080528316620001235760405162461bcd60e51b815260206004820181905260248201527f42616e6b2063616e206e6f7420626520746865207a65726f20616464726573736044820152606401620000bc565b6001600160a01b0382166200018a5760405162461bcd60e51b815260206004820152602660248201527f5442544320746f6b656e2063616e206e6f7420626520746865207a65726f206160448201526564647265737360d01b6064820152608401620000bc565b506001600160a01b0391821660a0521660c05262000260565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146200020957600080fd5b50565b6000806000606084860312156200022257600080fd5b83516200022f81620001f3565b60208501519093506200024281620001f3565b60408501519092506200025581620001f3565b809150509250925092565b60805160a05160c051613b136200031c600039600081816107330152818161098001528181610cf401528181611fb0015281816123b101528181612d6d01528181612ed8015261301f01526000818161057901528181610d6101528181610ebc01528181610f4a0152818161104f0152818161242d015281816125650152818161265601528181612f36015261307d01526000818161075a015281816115720152818161170e01528181611d620152612f650152613b136000f3fe608060405234801561001057600080fd5b50600436106103365760003560e01c80638532c511116101b2578063a410d29b116100f9578063c36b32b7116100a2578063e5d3d7141161007c578063e5d3d7141461072e578063e78cea9214610755578063f2fde38b1461077c578063fc4e51f61461078f57600080fd5b8063c36b32b7146106ff578063c7ba034714610712578063d0ff65b51461071e57600080fd5b8063b0b54895116100d3578063b0b54895146106cd578063b9f78798146106d7578063bc7b6b99146106f757600080fd5b8063a410d29b1461068f578063a526d83b14610697578063aa271e1a146106aa57600080fd5b8063951315261161015b5780639a508c8e116101355780639a508c8e1461066b578063a0712d6814610673578063a0cceb951461068657600080fd5b80639513152614610647578063983b2d56146106505780639a4e36d51461066357600080fd5b8063897f712c1161018c578063897f712c1461060f5780638da5cb5b146106235780638f4ffcb11461063457600080fd5b80638532c511146105d95780638623ec7b146105e957806388aaf0c8146105fc57600080fd5b806347c1ffdb116102815780636c626aa41161022a5780637445a5a0116102045780637445a5a01461054657806376cdb03b1461057457806380df5ed2146105b3578063820b5513146105c657600080fd5b80636c626aa4146104d0578063714041561461052b578063715018a61461053e57600080fd5b806364e779b11161025b57806364e779b1146104955780636abe3a6c146104a85780636b32810b146104bb57600080fd5b806347c1ffdb1461046357806353dce4df1461046b5780635ae2da461461047e57600080fd5b80633092afd5116102e3578063461c6373116102bd578063461c63731461042a578063475d05701461043d578063479aa9271461045057600080fd5b80633092afd5146103fb578063317dfa761461040e57806341906ab71461042157600080fd5b80631171bda9116103145780631171bda9146103b4578063124f65bd146103c75780632e73e398146103e857600080fd5b806309b53f511461033b5780630c68ba211461036c5780630f3425731461039f575b600080fd5b60005461035290600160a81b900463ffffffff1681565b60405163ffffffff90911681526020015b60405180910390f35b61038f61037a3660046133e9565b60036020526000908152604090205460ff1681565b6040519015158152602001610363565b6103b26103ad366004613418565b6107a2565b005b6103b26103c2366004613435565b610842565b6103da6103d5366004613476565b6108a3565b604051908152602001610363565b6103b26103f63660046134ef565b610908565b6103b26104093660046133e9565b6109f6565b6103b261041c366004613435565b610c65565b6103da60095481565b6103b26104383660046135a7565b610d56565b6103b261044b366004613613565b610eb1565b6103b261045e3660046133e9565b6110b2565b6103b26111b7565b6103b2610479366004613663565b611295565b60005461035290600160c81b900463ffffffff1681565b6103b26104a33660046136af565b6112b6565b6103b26104b6366004613476565b6112d3565b6104c3611820565b60405161036391906136c8565b61050a6104de3660046136af565b60046020526000908152604090205467ffffffffffffffff808216916801000000000000000090041682565b6040805167ffffffffffffffff938416815292909116602083015201610363565b6103b26105393660046133e9565b611882565b6103b261197b565b6105596105543660046136af565b6119cf565b60408051938452602084019290925290820152606001610363565b61059b7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610363565b6103b26105c1366004613476565b611a07565b6103b26105d4366004613476565b611bf3565b6006546103529063ffffffff1681565b61059b6105f73660046136af565b611f84565b600a5461059b906001600160a01b031681565b60005461038f90600160a01b900460ff1681565b6000546001600160a01b031661059b565b6103b2610642366004613715565b611fae565b6103da600b5481565b6103b261065e3660046133e9565b6120c3565b6103b2612200565b6103b26122de565b6103b26106813660046136af565b612535565b6103da60075481565b6103b261268d565b6103b26106a53660046133e9565b612775565b61038f6106b83660046133e9565b60016020526000908152604090205460ff1681565b6103da6201518081565b6103da6106e53660046133e9565b60056020526000908152604090205481565b6103b2612898565b6103b261070d366004613418565b61296f565b6103da6402540be40081565b6008546103529063ffffffff1681565b61059b7f000000000000000000000000000000000000000000000000000000000000000081565b61059b7f000000000000000000000000000000000000000000000000000000000000000081565b6103b261078a3660046133e9565b612a03565b6103b261079d3660046134ef565b612ad3565b6000546001600160a01b031633146107ef5760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064015b60405180910390fd5b426009556008805463ffffffff191663ffffffff83169081179091556040519081527f682bc0fb7e0d6bcb974cf556b95f68533cafc411d83d9f33ac192ccf45dda605906020015b60405180910390a150565b6000546001600160a01b0316331461088a5760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b61089e6001600160a01b0384168383612b68565b505050565b600082826040516020016108e692919091825260e01b7fffffffff0000000000000000000000000000000000000000000000000000000016602082015260240190565b6040516020818303038152906040528051906020012060001c90505b92915050565b6000546001600160a01b031633146109505760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b6040517ffc4e51f60000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063fc4e51f6906109bd9088908890889088908890600401613794565b600060405180830381600087803b1580156109d757600080fd5b505af11580156109eb573d6000803e3d6000fd5b505050505050505050565b33610a096000546001600160a01b031690565b6001600160a01b03161480610a2d57503360009081526003602052604090205460ff165b610a9f5760405162461bcd60e51b815260206004820152602360248201527f43616c6c6572206973206e6f7420746865206f776e6572206f7220677561726460448201527f69616e000000000000000000000000000000000000000000000000000000000060648201526084016107e6565b6001600160a01b03811660009081526001602052604090205460ff16610b075760405162461bcd60e51b815260206004820152601c60248201527f546869732061646472657373206973206e6f742061206d696e7465720000000060448201526064016107e6565b6001600160a01b0381166000908152600160205260408120805460ff191690555b600254811015610c2d57816001600160a01b031660028281548110610b4f57610b4f6137c7565b6000918252602090912001546001600160a01b031603610c1b5760028054610b79906001906137f3565b81548110610b8957610b896137c7565b600091825260209091200154600280546001600160a01b039092169183908110610bb557610bb56137c7565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506002805480610bf457610bf4613806565b600082815260209020810160001990810180546001600160a01b0319169055019055610c2d565b80610c258161381c565b915050610b28565b506040516001600160a01b038216907fe94479a9f7e1952cc78f2d6baab678adc1b772d936c6583def489e524cb6669290600090a250565b6000546001600160a01b03163314610cad5760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b6040517f1171bda90000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301528381166024830152604482018390527f00000000000000000000000000000000000000000000000000000000000000001690631171bda9906064015b600060405180830381600087803b158015610d3957600080fd5b505af1158015610d4d573d6000803e3d6000fd5b50505050505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610dce5760405162461bcd60e51b815260206004820152601660248201527f43616c6c6572206973206e6f74207468652042616e6b0000000000000000000060448201526064016107e6565b6000839003610e1f5760405162461bcd60e51b815260206004820152601760248201527f4e6f206465706f7369746f72732073706563696669656400000000000000000060448201526064016107e6565b60005b83811015610eaa576000858583818110610e3e57610e3e6137c7565b9050602002016020810190610e5391906133e9565b90506000848484818110610e6957610e696137c7565b905060200201359050610e9582610e90846402540be40085610e8b9190613835565b612be8565b612ceb565b50508080610ea29061381c565b915050610e22565b5050505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610f295760405162461bcd60e51b815260206004820152601660248201527f43616c6c6572206973206e6f74207468652042616e6b0000000000000000000060448201526064016107e6565b6040516370a0823160e01b81526001600160a01b03858116600483015284917f0000000000000000000000000000000000000000000000000000000000000000909116906370a0823190602401602060405180830381865afa158015610f93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fb7919061384c565b10156110105760405162461bcd60e51b815260206004820152602260248201527f416d6f756e7420657863656564732062616c616e636520696e207468652062616044820152616e6b60f01b60648201526084016107e6565b61102384610e906402540be40086613835565b604051631f1b6d2760e21b81526001600160a01b038581166004830152306024830152604482018590527f00000000000000000000000000000000000000000000000000000000000000001690637c6db49c906064015b600060405180830381600087803b15801561109457600080fd5b505af11580156110a8573d6000803e3d6000fd5b5050505050505050565b6000546001600160a01b031633146110fa5760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b6001600160a01b0381166111505760405162461bcd60e51b815260206004820181905260248201527f4e6577207661756c7420616464726573732063616e6e6f74206265207a65726f60448201526064016107e6565b604080516001600160a01b03831681524260208201527f5cc842cab066489e13292128663547c68705dbf476f0131e0107f155719c6124910160405180910390a142600b55600a80546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146111ff5760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b60075461120f8162015180612dc6565b600654600080547fffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffffff1663ffffffff909216600160a81b81029290921790556040519081527fa7f4ce7c3586e2000cdec6b25c5e7d0b20f9b4f435aa22d9c1feb32dbb506f779060200160405180910390a1506006805463ffffffff191690556000600755565b60006112a0846119cf565b505090506112b033828585612e6f565b50505050565b60006112c1826119cf565b505090506112cf3382612fb6565b5050565b3360009081526001602052604090205460ff166113325760405162461bcd60e51b815260206004820152601660248201527f43616c6c6572206973206e6f742061206d696e7465720000000000000000000060448201526064016107e6565b600054600160a01b900460ff161561138c5760405162461bcd60e51b815260206004820152601960248201527f4f7074696d6973746963206d696e74696e67207061757365640000000000000060448201526064016107e6565b600061139883836108a3565b600081815260046020526040812080549293509167ffffffffffffffff16900361142a5760405162461bcd60e51b815260206004820152603060248201527f4f7074696d6973746963206d696e74696e67206e6f742072657175657374656460448201527f20666f7220746865206465706f7369740000000000000000000000000000000060648201526084016107e6565b805468010000000000000000900467ffffffffffffffff16156114b55760405162461bcd60e51b815260206004820152603460248201527f4f7074696d6973746963206d696e74696e6720616c72656164792066696e616c60448201527f697a656420666f7220746865206465706f73697400000000000000000000000060648201526084016107e6565b60005481546114db91600160c81b900463ffffffff169067ffffffffffffffff16613865565b67ffffffffffffffff1642116115595760405162461bcd60e51b815260206004820152602b60248201527f4f7074696d6973746963206d696e74696e672064656c617920686173206e6f7460448201527f207061737365642079657400000000000000000000000000000000000000000060648201526084016107e6565b604051630b02c43d60e41b8152600481018390526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063b02c43d09060240160c060405180830381865afa1580156115c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e591906138b9565b90508060a0015163ffffffff166000146116415760405162461bcd60e51b815260206004820152601c60248201527f546865206465706f73697420697320616c72656164792073776570740000000060448201526064016107e6565b60006402540be4008260800151836020015161165d9190613966565b67ffffffffffffffff166116719190613835565b6000805491925090600160a81b900463ffffffff166116915760006116ab565b6000546116ab90600160a81b900463ffffffff168361399d565b83516001600160a01b0316600090815260056020526040812054919250906116d49084906139b1565b84516001600160a01b03166000908152600560205260409020819055845190915061170390610e9084866137f3565b8115611794576117947f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166361d027b36040518163ffffffff1660e01b8152600401602060405180830381865afa15801561176a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061178e91906139c4565b83612ceb565b84547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff16680100000000000000004267ffffffffffffffff160217855583516040518281526001600160a01b0390911690879033907f2cffebf26d639426e79514d100febae8b2c63e700e5dc0fa6c88a129633506369060200160405180910390a45050505050505050565b6060600280548060200260200160405190810160405280929190818152602001828054801561187857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161185a575b5050505050905090565b6000546001600160a01b031633146118ca5760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b6001600160a01b03811660009081526003602052604090205460ff166119325760405162461bcd60e51b815260206004820152601e60248201527f546869732061646472657373206973206e6f74206120677561726469616e000060448201526064016107e6565b6001600160a01b038116600081815260036020526040808220805460ff19169055517fb8107d0c6b40be480ce3172ee66ba6d64b71f6b1685a851340036e6e2e3e3c529190a250565b6000546001600160a01b031633146119c35760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b6119cd6000613105565b565b600080806119e26402540be400856139e1565b91506119ee82856137f3565b92506119ff6402540be4008461399d565b929491935050565b3360009081526003602052604090205460ff16611a665760405162461bcd60e51b815260206004820152601860248201527f43616c6c6572206973206e6f74206120677561726469616e000000000000000060448201526064016107e6565b6000611a7283836108a3565b600081815260046020526040812080549293509167ffffffffffffffff169003611b045760405162461bcd60e51b815260206004820152603060248201527f4f7074696d6973746963206d696e74696e67206e6f742072657175657374656460448201527f20666f7220746865206465706f7369740000000000000000000000000000000060648201526084016107e6565b805468010000000000000000900467ffffffffffffffff1615611b8f5760405162461bcd60e51b815260206004820152603460248201527f4f7074696d6973746963206d696e74696e6720616c72656164792066696e616c60448201527f697a656420666f7220746865206465706f73697400000000000000000000000060648201526084016107e6565b60008281526004602052604080822080547fffffffffffffffffffffffffffffffff0000000000000000000000000000000016905551839133917f1256b41d4b18d922811c358ab80cb0375aae28f45373de35cfda580662193fcd9190a350505050565b3360009081526001602052604090205460ff16611c525760405162461bcd60e51b815260206004820152601660248201527f43616c6c6572206973206e6f742061206d696e7465720000000000000000000060448201526064016107e6565b600054600160a01b900460ff1615611cac5760405162461bcd60e51b815260206004820152601960248201527f4f7074696d6973746963206d696e74696e67207061757365640000000000000060448201526064016107e6565b6000611cb883836108a3565b600081815260046020526040902080549192509067ffffffffffffffff1615611d495760405162461bcd60e51b815260206004820152603460248201527f4f7074696d6973746963206d696e74696e6720616c726561647920726571756560448201527f7374656420666f7220746865206465706f73697400000000000000000000000060648201526084016107e6565b604051630b02c43d60e41b8152600481018390526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063b02c43d09060240160c060405180830381865afa158015611db1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dd591906138b9565b9050806040015163ffffffff16600003611e3b5760405162461bcd60e51b815260206004820152602160248201527f546865206465706f73697420686173206e6f74206265656e2072657665616c656044820152601960fa1b60648201526084016107e6565b60a081015163ffffffff1615611e935760405162461bcd60e51b815260206004820152601c60248201527f546865206465706f73697420697320616c72656164792073776570740000000060448201526064016107e6565b60608101516001600160a01b03163014611eef5760405162461bcd60e51b815260206004820152601860248201527f556e6578706563746564207661756c742061646472657373000000000000000060448201526064016107e6565b815467ffffffffffffffff19164267ffffffffffffffff908116919091178355815160208301516001600160a01b0390911691859133917f36f39c606d55d7dd2a05b8c4e41e9a6ca8c501cea10009c1762f6826a146e05591611f59916402540be4009116613835565b60408051918252602082018b905263ffffffff8a169082015260600160405180910390a45050505050565b60028181548110611f9457600080fd5b6000918252602090912001546001600160a01b0316905081565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b03161461202f5760405162461bcd60e51b815260206004820152601160248201527f546f6b656e206973206e6f74205442544300000000000000000000000000000060448201526064016107e6565b336001600160a01b038416146120875760405162461bcd60e51b815260206004820152601860248201527f4f6e6c7920544254432063616c6c657220616c6c6f776564000000000000000060448201526064016107e6565b6000612092856119cf565b509091505060008290036120af576120aa8682612fb6565b6120bb565b6120bb86828585612e6f565b505050505050565b6000546001600160a01b0316331461210b5760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b6001600160a01b03811660009081526001602052604090205460ff16156121745760405162461bcd60e51b815260206004820181905260248201527f54686973206164647265737320697320616c72656164792061206d696e74657260448201526064016107e6565b6001600160a01b0381166000818152600160208190526040808320805460ff19168317905560028054928301815583527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace90910180546001600160a01b03191684179055517f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f69190a250565b6000546001600160a01b031633146122485760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b6009546122588162015180612dc6565b600854600080547fffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffff1663ffffffff909216600160c81b81029290921790556040519081527ff52de3377e3ae270d1e38f99b9b8d587814643811516ea55ba4d597f9950d4ec9060200160405180910390a1506008805463ffffffff191690556000600955565b6000546001600160a01b031633146123265760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b600b546123368162015180612dc6565b600a546040516001600160a01b0390911681527f81a9bb8030ed4116b405800280e065110a37afb57b69948e714c97fab23475ec9060200160405180910390a1600a546040517ff2fde38b0000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201527f00000000000000000000000000000000000000000000000000000000000000009091169063f2fde38b90602401600060405180830381600087803b1580156123f757600080fd5b505af115801561240b573d6000803e3d6000fd5b5050600a546040516370a0823160e01b81523060048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811694506356a6d9ef93509091169083906370a0823190602401602060405180830381865afa158015612483573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124a7919061384c565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561250557600080fd5b505af1158015612519573d6000803e3d6000fd5b5050600a80546001600160a01b031916905550506000600b5550565b600080612541836119cf565b6040516370a0823160e01b8152336004820152929450925082916001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691506370a0823190602401602060405180830381865afa1580156125ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d1919061384c565b101561262a5760405162461bcd60e51b815260206004820152602260248201527f416d6f756e7420657863656564732062616c616e636520696e207468652062616044820152616e6b60f01b60648201526084016107e6565b6126343383612ceb565b604051631f1b6d2760e21b8152336004820152306024820152604481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690637c6db49c90606401610d1f565b6000546001600160a01b031633146126d55760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b600054600160a01b900460ff16156127395760405162461bcd60e51b815260206004820152602160248201527f4f7074696d6973746963206d696e74696e6720616c72656164792070617573656044820152601960fa1b60648201526084016107e6565b6000805460ff60a01b1916600160a01b1781556040517f23a83c8aeda8c831401c17b5bfb8b2ead79fcfe9c027fe34a4f8576e2c7c74cc9190a1565b6000546001600160a01b031633146127bd5760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b6001600160a01b03811660009081526003602052604090205460ff161561284c5760405162461bcd60e51b815260206004820152602260248201527f54686973206164647265737320697320616c726561647920612067756172646960448201527f616e00000000000000000000000000000000000000000000000000000000000060648201526084016107e6565b6001600160a01b038116600081815260036020526040808220805460ff19166001179055517f038596bb31e2e7d3d9f184d4c98b310103f6d7f5830e5eec32bffe6f1728f9699190a250565b6000546001600160a01b031633146128e05760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b600054600160a01b900460ff166129395760405162461bcd60e51b815260206004820181905260248201527f4f7074696d6973746963206d696e74696e67206973206e6f742070617573656460448201526064016107e6565b6000805460ff60a01b191681556040517fcb27470ed9568d9eeb8939707bafc19404d908a26ce5f468a6aa781024fd6a839190a1565b6000546001600160a01b031633146129b75760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b426007556006805463ffffffff191663ffffffff83169081179091556040519081527f0dbfec7f12acffbb5cec595ac4370907eaf84caa7025dd71f4021433be79eba990602001610837565b6000546001600160a01b03163314612a4b5760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b6001600160a01b038116612ac75760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016107e6565b612ad081613105565b50565b6000546001600160a01b03163314612b1b5760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b6040517fb88d4fde0000000000000000000000000000000000000000000000000000000081526001600160a01b0386169063b88d4fde906109bd9030908890889088908890600401613794565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261089e908490613155565b6001600160a01b038216600090815260056020526040812054808203612c115782915050610902565b80831115612c78576001600160a01b0384166000818152600560209081526040808320839055519182527fb30abd1b9e3d58cd8525b3d5c5aa002db1e43a150af5b172a8d16efcc7a141f8910160405180910390a2612c7081846137f3565b915050610902565b612c8283826137f3565b6001600160a01b0385166000818152600560205260409020919091557fb30abd1b9e3d58cd8525b3d5c5aa002db1e43a150af5b172a8d16efcc7a141f8612cc985846137f3565b60405190815260200160405180910390a26000915050610902565b5092915050565b816001600160a01b03167f30385c845b448a36257a6a1716e6ad2e1bc2cbe333cde1e69fe849ad6511adfe82604051612d2691815260200190565b60405180910390a26040517f40c10f190000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018390527f000000000000000000000000000000000000000000000000000000000000000016906340c10f19906044015b600060405180830381600087803b158015612db257600080fd5b505af11580156120bb573d6000803e3d6000fd5b60008211612e165760405162461bcd60e51b815260206004820152601460248201527f4368616e6765206e6f7420696e6974696174656400000000000000000000000060448201526064016107e6565b80612e2183426137f3565b10156112cf5760405162461bcd60e51b815260206004820181905260248201527f476f7665726e616e63652064656c617920686173206e6f7420656c617073656460448201526064016107e6565b836001600160a01b03167f68751a4c3821398cb63d11609eca2440742ef19446f0c0261bfa8a13dd0748b884604051612eaa91815260200190565b60405180910390a260405163079cc67960e41b81526001600160a01b038581166004830152602482018590527f000000000000000000000000000000000000000000000000000000000000000016906379cc679090604401600060405180830381600087803b158015612f1c57600080fd5b505af1158015612f30573d6000803e3d6000fd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634a38757e7f00000000000000000000000000000000000000000000000000000000000000006402540be40086612f95919061399d565b85856040518563ffffffff1660e01b815260040161107a94939291906139f5565b816001600160a01b03167f68751a4c3821398cb63d11609eca2440742ef19446f0c0261bfa8a13dd0748b882604051612ff191815260200190565b60405180910390a260405163079cc67960e41b81526001600160a01b038381166004830152602482018390527f000000000000000000000000000000000000000000000000000000000000000016906379cc679090604401600060405180830381600087803b15801561306357600080fd5b505af1158015613077573d6000803e3d6000fd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166356a6d9ef836402540be400846130bc919061399d565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b0390921660048301526024820152604401612d98565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006131aa826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661323a9092919063ffffffff16565b80519091501561089e57808060200190518101906131c89190613a28565b61089e5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016107e6565b60606132498484600085613253565b90505b9392505050565b6060824710156132cb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016107e6565b6001600160a01b0385163b6133225760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107e6565b600080866001600160a01b0316858760405161333e9190613a6e565b60006040518083038185875af1925050503d806000811461337b576040519150601f19603f3d011682016040523d82523d6000602084013e613380565b606091505b509150915061339082828661339b565b979650505050505050565b606083156133aa57508161324c565b8251156133ba5782518084602001fd5b8160405162461bcd60e51b81526004016107e69190613a8a565b6001600160a01b0381168114612ad057600080fd5b6000602082840312156133fb57600080fd5b813561324c816133d4565b63ffffffff81168114612ad057600080fd5b60006020828403121561342a57600080fd5b813561324c81613406565b60008060006060848603121561344a57600080fd5b8335613455816133d4565b92506020840135613465816133d4565b929592945050506040919091013590565b6000806040838503121561348957600080fd5b82359150602083013561349b81613406565b809150509250929050565b60008083601f8401126134b857600080fd5b50813567ffffffffffffffff8111156134d057600080fd5b6020830191508360208285010111156134e857600080fd5b9250929050565b60008060008060006080868803121561350757600080fd5b8535613512816133d4565b94506020860135613522816133d4565b935060408601359250606086013567ffffffffffffffff81111561354557600080fd5b613551888289016134a6565b969995985093965092949392505050565b60008083601f84011261357457600080fd5b50813567ffffffffffffffff81111561358c57600080fd5b6020830191508360208260051b85010111156134e857600080fd5b600080600080604085870312156135bd57600080fd5b843567ffffffffffffffff808211156135d557600080fd5b6135e188838901613562565b909650945060208701359150808211156135fa57600080fd5b5061360787828801613562565b95989497509550505050565b6000806000806060858703121561362957600080fd5b8435613634816133d4565b935060208501359250604085013567ffffffffffffffff81111561365757600080fd5b613607878288016134a6565b60008060006040848603121561367857600080fd5b83359250602084013567ffffffffffffffff81111561369657600080fd5b6136a2868287016134a6565b9497909650939450505050565b6000602082840312156136c157600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b818110156137095783516001600160a01b0316835292840192918401916001016136e4565b50909695505050505050565b60008060008060006080868803121561372d57600080fd5b8535613738816133d4565b945060208601359350604086013561374f816133d4565b9250606086013567ffffffffffffffff81111561354557600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60006001600160a01b0380881683528087166020840152508460408301526080606083015261339060808301848661376b565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b81810381811115610902576109026137dd565b634e487b7160e01b600052603160045260246000fd5b60006001820161382e5761382e6137dd565b5060010190565b8082028115828204841417610902576109026137dd565b60006020828403121561385e57600080fd5b5051919050565b67ffffffffffffffff818116838216019080821115612ce457612ce46137dd565b8051613891816133d4565b919050565b805167ffffffffffffffff8116811461389157600080fd5b805161389181613406565b600060c082840312156138cb57600080fd5b60405160c0810181811067ffffffffffffffff821117156138fc57634e487b7160e01b600052604160045260246000fd5b60405261390883613886565b815261391660208401613896565b6020820152613927604084016138ae565b604082015261393860608401613886565b606082015261394960808401613896565b608082015261395a60a084016138ae565b60a08201529392505050565b67ffffffffffffffff828116828216039080821115612ce457612ce46137dd565b634e487b7160e01b600052601260045260246000fd5b6000826139ac576139ac613987565b500490565b80820180821115610902576109026137dd565b6000602082840312156139d657600080fd5b815161324c816133d4565b6000826139f0576139f0613987565b500690565b6001600160a01b0385168152836020820152606060408201526000613a1e60608301848661376b565b9695505050505050565b600060208284031215613a3a57600080fd5b8151801515811461324c57600080fd5b60005b83811015613a65578181015183820152602001613a4d565b50506000910152565b60008251613a80818460208701613a4a565b9190910192915050565b6020815260008251806020840152613aa9816040850160208701613a4a565b601f01601f1916919091016040019291505056fe4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a26469706673582212209a07381069555c36987780153c945020363fa37b34dc75e1273fdc2b8ab2e0d464736f6c6343000811003300000000000000000000000065fbae61ad2c8836ffbfb502a0da41b0789d9fc600000000000000000000000018084fba666a33d37592fa2633fd49a74dd93a880000000000000000000000005e4861a80b55f035d899f66772117f00fa0e8e7b

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106103365760003560e01c80638532c511116101b2578063a410d29b116100f9578063c36b32b7116100a2578063e5d3d7141161007c578063e5d3d7141461072e578063e78cea9214610755578063f2fde38b1461077c578063fc4e51f61461078f57600080fd5b8063c36b32b7146106ff578063c7ba034714610712578063d0ff65b51461071e57600080fd5b8063b0b54895116100d3578063b0b54895146106cd578063b9f78798146106d7578063bc7b6b99146106f757600080fd5b8063a410d29b1461068f578063a526d83b14610697578063aa271e1a146106aa57600080fd5b8063951315261161015b5780639a508c8e116101355780639a508c8e1461066b578063a0712d6814610673578063a0cceb951461068657600080fd5b80639513152614610647578063983b2d56146106505780639a4e36d51461066357600080fd5b8063897f712c1161018c578063897f712c1461060f5780638da5cb5b146106235780638f4ffcb11461063457600080fd5b80638532c511146105d95780638623ec7b146105e957806388aaf0c8146105fc57600080fd5b806347c1ffdb116102815780636c626aa41161022a5780637445a5a0116102045780637445a5a01461054657806376cdb03b1461057457806380df5ed2146105b3578063820b5513146105c657600080fd5b80636c626aa4146104d0578063714041561461052b578063715018a61461053e57600080fd5b806364e779b11161025b57806364e779b1146104955780636abe3a6c146104a85780636b32810b146104bb57600080fd5b806347c1ffdb1461046357806353dce4df1461046b5780635ae2da461461047e57600080fd5b80633092afd5116102e3578063461c6373116102bd578063461c63731461042a578063475d05701461043d578063479aa9271461045057600080fd5b80633092afd5146103fb578063317dfa761461040e57806341906ab71461042157600080fd5b80631171bda9116103145780631171bda9146103b4578063124f65bd146103c75780632e73e398146103e857600080fd5b806309b53f511461033b5780630c68ba211461036c5780630f3425731461039f575b600080fd5b60005461035290600160a81b900463ffffffff1681565b60405163ffffffff90911681526020015b60405180910390f35b61038f61037a3660046133e9565b60036020526000908152604090205460ff1681565b6040519015158152602001610363565b6103b26103ad366004613418565b6107a2565b005b6103b26103c2366004613435565b610842565b6103da6103d5366004613476565b6108a3565b604051908152602001610363565b6103b26103f63660046134ef565b610908565b6103b26104093660046133e9565b6109f6565b6103b261041c366004613435565b610c65565b6103da60095481565b6103b26104383660046135a7565b610d56565b6103b261044b366004613613565b610eb1565b6103b261045e3660046133e9565b6110b2565b6103b26111b7565b6103b2610479366004613663565b611295565b60005461035290600160c81b900463ffffffff1681565b6103b26104a33660046136af565b6112b6565b6103b26104b6366004613476565b6112d3565b6104c3611820565b60405161036391906136c8565b61050a6104de3660046136af565b60046020526000908152604090205467ffffffffffffffff808216916801000000000000000090041682565b6040805167ffffffffffffffff938416815292909116602083015201610363565b6103b26105393660046133e9565b611882565b6103b261197b565b6105596105543660046136af565b6119cf565b60408051938452602084019290925290820152606001610363565b61059b7f00000000000000000000000065fbae61ad2c8836ffbfb502a0da41b0789d9fc681565b6040516001600160a01b039091168152602001610363565b6103b26105c1366004613476565b611a07565b6103b26105d4366004613476565b611bf3565b6006546103529063ffffffff1681565b61059b6105f73660046136af565b611f84565b600a5461059b906001600160a01b031681565b60005461038f90600160a01b900460ff1681565b6000546001600160a01b031661059b565b6103b2610642366004613715565b611fae565b6103da600b5481565b6103b261065e3660046133e9565b6120c3565b6103b2612200565b6103b26122de565b6103b26106813660046136af565b612535565b6103da60075481565b6103b261268d565b6103b26106a53660046133e9565b612775565b61038f6106b83660046133e9565b60016020526000908152604090205460ff1681565b6103da6201518081565b6103da6106e53660046133e9565b60056020526000908152604090205481565b6103b2612898565b6103b261070d366004613418565b61296f565b6103da6402540be40081565b6008546103529063ffffffff1681565b61059b7f00000000000000000000000018084fba666a33d37592fa2633fd49a74dd93a8881565b61059b7f0000000000000000000000005e4861a80b55f035d899f66772117f00fa0e8e7b81565b6103b261078a3660046133e9565b612a03565b6103b261079d3660046134ef565b612ad3565b6000546001600160a01b031633146107ef5760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064015b60405180910390fd5b426009556008805463ffffffff191663ffffffff83169081179091556040519081527f682bc0fb7e0d6bcb974cf556b95f68533cafc411d83d9f33ac192ccf45dda605906020015b60405180910390a150565b6000546001600160a01b0316331461088a5760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b61089e6001600160a01b0384168383612b68565b505050565b600082826040516020016108e692919091825260e01b7fffffffff0000000000000000000000000000000000000000000000000000000016602082015260240190565b6040516020818303038152906040528051906020012060001c90505b92915050565b6000546001600160a01b031633146109505760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b6040517ffc4e51f60000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000018084fba666a33d37592fa2633fd49a74dd93a88169063fc4e51f6906109bd9088908890889088908890600401613794565b600060405180830381600087803b1580156109d757600080fd5b505af11580156109eb573d6000803e3d6000fd5b505050505050505050565b33610a096000546001600160a01b031690565b6001600160a01b03161480610a2d57503360009081526003602052604090205460ff165b610a9f5760405162461bcd60e51b815260206004820152602360248201527f43616c6c6572206973206e6f7420746865206f776e6572206f7220677561726460448201527f69616e000000000000000000000000000000000000000000000000000000000060648201526084016107e6565b6001600160a01b03811660009081526001602052604090205460ff16610b075760405162461bcd60e51b815260206004820152601c60248201527f546869732061646472657373206973206e6f742061206d696e7465720000000060448201526064016107e6565b6001600160a01b0381166000908152600160205260408120805460ff191690555b600254811015610c2d57816001600160a01b031660028281548110610b4f57610b4f6137c7565b6000918252602090912001546001600160a01b031603610c1b5760028054610b79906001906137f3565b81548110610b8957610b896137c7565b600091825260209091200154600280546001600160a01b039092169183908110610bb557610bb56137c7565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506002805480610bf457610bf4613806565b600082815260209020810160001990810180546001600160a01b0319169055019055610c2d565b80610c258161381c565b915050610b28565b506040516001600160a01b038216907fe94479a9f7e1952cc78f2d6baab678adc1b772d936c6583def489e524cb6669290600090a250565b6000546001600160a01b03163314610cad5760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b6040517f1171bda90000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301528381166024830152604482018390527f00000000000000000000000018084fba666a33d37592fa2633fd49a74dd93a881690631171bda9906064015b600060405180830381600087803b158015610d3957600080fd5b505af1158015610d4d573d6000803e3d6000fd5b50505050505050565b336001600160a01b037f00000000000000000000000065fbae61ad2c8836ffbfb502a0da41b0789d9fc61614610dce5760405162461bcd60e51b815260206004820152601660248201527f43616c6c6572206973206e6f74207468652042616e6b0000000000000000000060448201526064016107e6565b6000839003610e1f5760405162461bcd60e51b815260206004820152601760248201527f4e6f206465706f7369746f72732073706563696669656400000000000000000060448201526064016107e6565b60005b83811015610eaa576000858583818110610e3e57610e3e6137c7565b9050602002016020810190610e5391906133e9565b90506000848484818110610e6957610e696137c7565b905060200201359050610e9582610e90846402540be40085610e8b9190613835565b612be8565b612ceb565b50508080610ea29061381c565b915050610e22565b5050505050565b336001600160a01b037f00000000000000000000000065fbae61ad2c8836ffbfb502a0da41b0789d9fc61614610f295760405162461bcd60e51b815260206004820152601660248201527f43616c6c6572206973206e6f74207468652042616e6b0000000000000000000060448201526064016107e6565b6040516370a0823160e01b81526001600160a01b03858116600483015284917f00000000000000000000000065fbae61ad2c8836ffbfb502a0da41b0789d9fc6909116906370a0823190602401602060405180830381865afa158015610f93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fb7919061384c565b10156110105760405162461bcd60e51b815260206004820152602260248201527f416d6f756e7420657863656564732062616c616e636520696e207468652062616044820152616e6b60f01b60648201526084016107e6565b61102384610e906402540be40086613835565b604051631f1b6d2760e21b81526001600160a01b038581166004830152306024830152604482018590527f00000000000000000000000065fbae61ad2c8836ffbfb502a0da41b0789d9fc61690637c6db49c906064015b600060405180830381600087803b15801561109457600080fd5b505af11580156110a8573d6000803e3d6000fd5b5050505050505050565b6000546001600160a01b031633146110fa5760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b6001600160a01b0381166111505760405162461bcd60e51b815260206004820181905260248201527f4e6577207661756c7420616464726573732063616e6e6f74206265207a65726f60448201526064016107e6565b604080516001600160a01b03831681524260208201527f5cc842cab066489e13292128663547c68705dbf476f0131e0107f155719c6124910160405180910390a142600b55600a80546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146111ff5760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b60075461120f8162015180612dc6565b600654600080547fffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffffff1663ffffffff909216600160a81b81029290921790556040519081527fa7f4ce7c3586e2000cdec6b25c5e7d0b20f9b4f435aa22d9c1feb32dbb506f779060200160405180910390a1506006805463ffffffff191690556000600755565b60006112a0846119cf565b505090506112b033828585612e6f565b50505050565b60006112c1826119cf565b505090506112cf3382612fb6565b5050565b3360009081526001602052604090205460ff166113325760405162461bcd60e51b815260206004820152601660248201527f43616c6c6572206973206e6f742061206d696e7465720000000000000000000060448201526064016107e6565b600054600160a01b900460ff161561138c5760405162461bcd60e51b815260206004820152601960248201527f4f7074696d6973746963206d696e74696e67207061757365640000000000000060448201526064016107e6565b600061139883836108a3565b600081815260046020526040812080549293509167ffffffffffffffff16900361142a5760405162461bcd60e51b815260206004820152603060248201527f4f7074696d6973746963206d696e74696e67206e6f742072657175657374656460448201527f20666f7220746865206465706f7369740000000000000000000000000000000060648201526084016107e6565b805468010000000000000000900467ffffffffffffffff16156114b55760405162461bcd60e51b815260206004820152603460248201527f4f7074696d6973746963206d696e74696e6720616c72656164792066696e616c60448201527f697a656420666f7220746865206465706f73697400000000000000000000000060648201526084016107e6565b60005481546114db91600160c81b900463ffffffff169067ffffffffffffffff16613865565b67ffffffffffffffff1642116115595760405162461bcd60e51b815260206004820152602b60248201527f4f7074696d6973746963206d696e74696e672064656c617920686173206e6f7460448201527f207061737365642079657400000000000000000000000000000000000000000060648201526084016107e6565b604051630b02c43d60e41b8152600481018390526000907f0000000000000000000000005e4861a80b55f035d899f66772117f00fa0e8e7b6001600160a01b03169063b02c43d09060240160c060405180830381865afa1580156115c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e591906138b9565b90508060a0015163ffffffff166000146116415760405162461bcd60e51b815260206004820152601c60248201527f546865206465706f73697420697320616c72656164792073776570740000000060448201526064016107e6565b60006402540be4008260800151836020015161165d9190613966565b67ffffffffffffffff166116719190613835565b6000805491925090600160a81b900463ffffffff166116915760006116ab565b6000546116ab90600160a81b900463ffffffff168361399d565b83516001600160a01b0316600090815260056020526040812054919250906116d49084906139b1565b84516001600160a01b03166000908152600560205260409020819055845190915061170390610e9084866137f3565b8115611794576117947f0000000000000000000000005e4861a80b55f035d899f66772117f00fa0e8e7b6001600160a01b03166361d027b36040518163ffffffff1660e01b8152600401602060405180830381865afa15801561176a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061178e91906139c4565b83612ceb565b84547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff16680100000000000000004267ffffffffffffffff160217855583516040518281526001600160a01b0390911690879033907f2cffebf26d639426e79514d100febae8b2c63e700e5dc0fa6c88a129633506369060200160405180910390a45050505050505050565b6060600280548060200260200160405190810160405280929190818152602001828054801561187857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161185a575b5050505050905090565b6000546001600160a01b031633146118ca5760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b6001600160a01b03811660009081526003602052604090205460ff166119325760405162461bcd60e51b815260206004820152601e60248201527f546869732061646472657373206973206e6f74206120677561726469616e000060448201526064016107e6565b6001600160a01b038116600081815260036020526040808220805460ff19169055517fb8107d0c6b40be480ce3172ee66ba6d64b71f6b1685a851340036e6e2e3e3c529190a250565b6000546001600160a01b031633146119c35760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b6119cd6000613105565b565b600080806119e26402540be400856139e1565b91506119ee82856137f3565b92506119ff6402540be4008461399d565b929491935050565b3360009081526003602052604090205460ff16611a665760405162461bcd60e51b815260206004820152601860248201527f43616c6c6572206973206e6f74206120677561726469616e000000000000000060448201526064016107e6565b6000611a7283836108a3565b600081815260046020526040812080549293509167ffffffffffffffff169003611b045760405162461bcd60e51b815260206004820152603060248201527f4f7074696d6973746963206d696e74696e67206e6f742072657175657374656460448201527f20666f7220746865206465706f7369740000000000000000000000000000000060648201526084016107e6565b805468010000000000000000900467ffffffffffffffff1615611b8f5760405162461bcd60e51b815260206004820152603460248201527f4f7074696d6973746963206d696e74696e6720616c72656164792066696e616c60448201527f697a656420666f7220746865206465706f73697400000000000000000000000060648201526084016107e6565b60008281526004602052604080822080547fffffffffffffffffffffffffffffffff0000000000000000000000000000000016905551839133917f1256b41d4b18d922811c358ab80cb0375aae28f45373de35cfda580662193fcd9190a350505050565b3360009081526001602052604090205460ff16611c525760405162461bcd60e51b815260206004820152601660248201527f43616c6c6572206973206e6f742061206d696e7465720000000000000000000060448201526064016107e6565b600054600160a01b900460ff1615611cac5760405162461bcd60e51b815260206004820152601960248201527f4f7074696d6973746963206d696e74696e67207061757365640000000000000060448201526064016107e6565b6000611cb883836108a3565b600081815260046020526040902080549192509067ffffffffffffffff1615611d495760405162461bcd60e51b815260206004820152603460248201527f4f7074696d6973746963206d696e74696e6720616c726561647920726571756560448201527f7374656420666f7220746865206465706f73697400000000000000000000000060648201526084016107e6565b604051630b02c43d60e41b8152600481018390526000907f0000000000000000000000005e4861a80b55f035d899f66772117f00fa0e8e7b6001600160a01b03169063b02c43d09060240160c060405180830381865afa158015611db1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dd591906138b9565b9050806040015163ffffffff16600003611e3b5760405162461bcd60e51b815260206004820152602160248201527f546865206465706f73697420686173206e6f74206265656e2072657665616c656044820152601960fa1b60648201526084016107e6565b60a081015163ffffffff1615611e935760405162461bcd60e51b815260206004820152601c60248201527f546865206465706f73697420697320616c72656164792073776570740000000060448201526064016107e6565b60608101516001600160a01b03163014611eef5760405162461bcd60e51b815260206004820152601860248201527f556e6578706563746564207661756c742061646472657373000000000000000060448201526064016107e6565b815467ffffffffffffffff19164267ffffffffffffffff908116919091178355815160208301516001600160a01b0390911691859133917f36f39c606d55d7dd2a05b8c4e41e9a6ca8c501cea10009c1762f6826a146e05591611f59916402540be4009116613835565b60408051918252602082018b905263ffffffff8a169082015260600160405180910390a45050505050565b60028181548110611f9457600080fd5b6000918252602090912001546001600160a01b0316905081565b7f00000000000000000000000018084fba666a33d37592fa2633fd49a74dd93a886001600160a01b0316836001600160a01b03161461202f5760405162461bcd60e51b815260206004820152601160248201527f546f6b656e206973206e6f74205442544300000000000000000000000000000060448201526064016107e6565b336001600160a01b038416146120875760405162461bcd60e51b815260206004820152601860248201527f4f6e6c7920544254432063616c6c657220616c6c6f776564000000000000000060448201526064016107e6565b6000612092856119cf565b509091505060008290036120af576120aa8682612fb6565b6120bb565b6120bb86828585612e6f565b505050505050565b6000546001600160a01b0316331461210b5760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b6001600160a01b03811660009081526001602052604090205460ff16156121745760405162461bcd60e51b815260206004820181905260248201527f54686973206164647265737320697320616c72656164792061206d696e74657260448201526064016107e6565b6001600160a01b0381166000818152600160208190526040808320805460ff19168317905560028054928301815583527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace90910180546001600160a01b03191684179055517f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f69190a250565b6000546001600160a01b031633146122485760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b6009546122588162015180612dc6565b600854600080547fffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffff1663ffffffff909216600160c81b81029290921790556040519081527ff52de3377e3ae270d1e38f99b9b8d587814643811516ea55ba4d597f9950d4ec9060200160405180910390a1506008805463ffffffff191690556000600955565b6000546001600160a01b031633146123265760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b600b546123368162015180612dc6565b600a546040516001600160a01b0390911681527f81a9bb8030ed4116b405800280e065110a37afb57b69948e714c97fab23475ec9060200160405180910390a1600a546040517ff2fde38b0000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201527f00000000000000000000000018084fba666a33d37592fa2633fd49a74dd93a889091169063f2fde38b90602401600060405180830381600087803b1580156123f757600080fd5b505af115801561240b573d6000803e3d6000fd5b5050600a546040516370a0823160e01b81523060048201526001600160a01b037f00000000000000000000000065fbae61ad2c8836ffbfb502a0da41b0789d9fc6811694506356a6d9ef93509091169083906370a0823190602401602060405180830381865afa158015612483573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124a7919061384c565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561250557600080fd5b505af1158015612519573d6000803e3d6000fd5b5050600a80546001600160a01b031916905550506000600b5550565b600080612541836119cf565b6040516370a0823160e01b8152336004820152929450925082916001600160a01b037f00000000000000000000000065fbae61ad2c8836ffbfb502a0da41b0789d9fc61691506370a0823190602401602060405180830381865afa1580156125ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d1919061384c565b101561262a5760405162461bcd60e51b815260206004820152602260248201527f416d6f756e7420657863656564732062616c616e636520696e207468652062616044820152616e6b60f01b60648201526084016107e6565b6126343383612ceb565b604051631f1b6d2760e21b8152336004820152306024820152604481018290527f00000000000000000000000065fbae61ad2c8836ffbfb502a0da41b0789d9fc66001600160a01b031690637c6db49c90606401610d1f565b6000546001600160a01b031633146126d55760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b600054600160a01b900460ff16156127395760405162461bcd60e51b815260206004820152602160248201527f4f7074696d6973746963206d696e74696e6720616c72656164792070617573656044820152601960fa1b60648201526084016107e6565b6000805460ff60a01b1916600160a01b1781556040517f23a83c8aeda8c831401c17b5bfb8b2ead79fcfe9c027fe34a4f8576e2c7c74cc9190a1565b6000546001600160a01b031633146127bd5760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b6001600160a01b03811660009081526003602052604090205460ff161561284c5760405162461bcd60e51b815260206004820152602260248201527f54686973206164647265737320697320616c726561647920612067756172646960448201527f616e00000000000000000000000000000000000000000000000000000000000060648201526084016107e6565b6001600160a01b038116600081815260036020526040808220805460ff19166001179055517f038596bb31e2e7d3d9f184d4c98b310103f6d7f5830e5eec32bffe6f1728f9699190a250565b6000546001600160a01b031633146128e05760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b600054600160a01b900460ff166129395760405162461bcd60e51b815260206004820181905260248201527f4f7074696d6973746963206d696e74696e67206973206e6f742070617573656460448201526064016107e6565b6000805460ff60a01b191681556040517fcb27470ed9568d9eeb8939707bafc19404d908a26ce5f468a6aa781024fd6a839190a1565b6000546001600160a01b031633146129b75760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b426007556006805463ffffffff191663ffffffff83169081179091556040519081527f0dbfec7f12acffbb5cec595ac4370907eaf84caa7025dd71f4021433be79eba990602001610837565b6000546001600160a01b03163314612a4b5760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b6001600160a01b038116612ac75760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016107e6565b612ad081613105565b50565b6000546001600160a01b03163314612b1b5760405162461bcd60e51b81526020600482018190526024820152600080516020613abe83398151915260448201526064016107e6565b6040517fb88d4fde0000000000000000000000000000000000000000000000000000000081526001600160a01b0386169063b88d4fde906109bd9030908890889088908890600401613794565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261089e908490613155565b6001600160a01b038216600090815260056020526040812054808203612c115782915050610902565b80831115612c78576001600160a01b0384166000818152600560209081526040808320839055519182527fb30abd1b9e3d58cd8525b3d5c5aa002db1e43a150af5b172a8d16efcc7a141f8910160405180910390a2612c7081846137f3565b915050610902565b612c8283826137f3565b6001600160a01b0385166000818152600560205260409020919091557fb30abd1b9e3d58cd8525b3d5c5aa002db1e43a150af5b172a8d16efcc7a141f8612cc985846137f3565b60405190815260200160405180910390a26000915050610902565b5092915050565b816001600160a01b03167f30385c845b448a36257a6a1716e6ad2e1bc2cbe333cde1e69fe849ad6511adfe82604051612d2691815260200190565b60405180910390a26040517f40c10f190000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018390527f00000000000000000000000018084fba666a33d37592fa2633fd49a74dd93a8816906340c10f19906044015b600060405180830381600087803b158015612db257600080fd5b505af11580156120bb573d6000803e3d6000fd5b60008211612e165760405162461bcd60e51b815260206004820152601460248201527f4368616e6765206e6f7420696e6974696174656400000000000000000000000060448201526064016107e6565b80612e2183426137f3565b10156112cf5760405162461bcd60e51b815260206004820181905260248201527f476f7665726e616e63652064656c617920686173206e6f7420656c617073656460448201526064016107e6565b836001600160a01b03167f68751a4c3821398cb63d11609eca2440742ef19446f0c0261bfa8a13dd0748b884604051612eaa91815260200190565b60405180910390a260405163079cc67960e41b81526001600160a01b038581166004830152602482018590527f00000000000000000000000018084fba666a33d37592fa2633fd49a74dd93a8816906379cc679090604401600060405180830381600087803b158015612f1c57600080fd5b505af1158015612f30573d6000803e3d6000fd5b505050507f00000000000000000000000065fbae61ad2c8836ffbfb502a0da41b0789d9fc66001600160a01b0316634a38757e7f0000000000000000000000005e4861a80b55f035d899f66772117f00fa0e8e7b6402540be40086612f95919061399d565b85856040518563ffffffff1660e01b815260040161107a94939291906139f5565b816001600160a01b03167f68751a4c3821398cb63d11609eca2440742ef19446f0c0261bfa8a13dd0748b882604051612ff191815260200190565b60405180910390a260405163079cc67960e41b81526001600160a01b038381166004830152602482018390527f00000000000000000000000018084fba666a33d37592fa2633fd49a74dd93a8816906379cc679090604401600060405180830381600087803b15801561306357600080fd5b505af1158015613077573d6000803e3d6000fd5b505050507f00000000000000000000000065fbae61ad2c8836ffbfb502a0da41b0789d9fc66001600160a01b03166356a6d9ef836402540be400846130bc919061399d565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b0390921660048301526024820152604401612d98565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006131aa826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661323a9092919063ffffffff16565b80519091501561089e57808060200190518101906131c89190613a28565b61089e5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016107e6565b60606132498484600085613253565b90505b9392505050565b6060824710156132cb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016107e6565b6001600160a01b0385163b6133225760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107e6565b600080866001600160a01b0316858760405161333e9190613a6e565b60006040518083038185875af1925050503d806000811461337b576040519150601f19603f3d011682016040523d82523d6000602084013e613380565b606091505b509150915061339082828661339b565b979650505050505050565b606083156133aa57508161324c565b8251156133ba5782518084602001fd5b8160405162461bcd60e51b81526004016107e69190613a8a565b6001600160a01b0381168114612ad057600080fd5b6000602082840312156133fb57600080fd5b813561324c816133d4565b63ffffffff81168114612ad057600080fd5b60006020828403121561342a57600080fd5b813561324c81613406565b60008060006060848603121561344a57600080fd5b8335613455816133d4565b92506020840135613465816133d4565b929592945050506040919091013590565b6000806040838503121561348957600080fd5b82359150602083013561349b81613406565b809150509250929050565b60008083601f8401126134b857600080fd5b50813567ffffffffffffffff8111156134d057600080fd5b6020830191508360208285010111156134e857600080fd5b9250929050565b60008060008060006080868803121561350757600080fd5b8535613512816133d4565b94506020860135613522816133d4565b935060408601359250606086013567ffffffffffffffff81111561354557600080fd5b613551888289016134a6565b969995985093965092949392505050565b60008083601f84011261357457600080fd5b50813567ffffffffffffffff81111561358c57600080fd5b6020830191508360208260051b85010111156134e857600080fd5b600080600080604085870312156135bd57600080fd5b843567ffffffffffffffff808211156135d557600080fd5b6135e188838901613562565b909650945060208701359150808211156135fa57600080fd5b5061360787828801613562565b95989497509550505050565b6000806000806060858703121561362957600080fd5b8435613634816133d4565b935060208501359250604085013567ffffffffffffffff81111561365757600080fd5b613607878288016134a6565b60008060006040848603121561367857600080fd5b83359250602084013567ffffffffffffffff81111561369657600080fd5b6136a2868287016134a6565b9497909650939450505050565b6000602082840312156136c157600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b818110156137095783516001600160a01b0316835292840192918401916001016136e4565b50909695505050505050565b60008060008060006080868803121561372d57600080fd5b8535613738816133d4565b945060208601359350604086013561374f816133d4565b9250606086013567ffffffffffffffff81111561354557600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60006001600160a01b0380881683528087166020840152508460408301526080606083015261339060808301848661376b565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b81810381811115610902576109026137dd565b634e487b7160e01b600052603160045260246000fd5b60006001820161382e5761382e6137dd565b5060010190565b8082028115828204841417610902576109026137dd565b60006020828403121561385e57600080fd5b5051919050565b67ffffffffffffffff818116838216019080821115612ce457612ce46137dd565b8051613891816133d4565b919050565b805167ffffffffffffffff8116811461389157600080fd5b805161389181613406565b600060c082840312156138cb57600080fd5b60405160c0810181811067ffffffffffffffff821117156138fc57634e487b7160e01b600052604160045260246000fd5b60405261390883613886565b815261391660208401613896565b6020820152613927604084016138ae565b604082015261393860608401613886565b606082015261394960808401613896565b608082015261395a60a084016138ae565b60a08201529392505050565b67ffffffffffffffff828116828216039080821115612ce457612ce46137dd565b634e487b7160e01b600052601260045260246000fd5b6000826139ac576139ac613987565b500490565b80820180821115610902576109026137dd565b6000602082840312156139d657600080fd5b815161324c816133d4565b6000826139f0576139f0613987565b500690565b6001600160a01b0385168152836020820152606060408201526000613a1e60608301848661376b565b9695505050505050565b600060208284031215613a3a57600080fd5b8151801515811461324c57600080fd5b60005b83811015613a65578181015183820152602001613a4d565b50506000910152565b60008251613a80818460208701613a4a565b9190910192915050565b6020815260008251806020840152613aa9816040850160208701613a4a565b601f01601f1916919091016040019291505056fe4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a26469706673582212209a07381069555c36987780153c945020363fa37b34dc75e1273fdc2b8ab2e0d464736f6c63430008110033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

00000000000000000000000065fbae61ad2c8836ffbfb502a0da41b0789d9fc600000000000000000000000018084fba666a33d37592fa2633fd49a74dd93a880000000000000000000000005e4861a80b55f035d899f66772117f00fa0e8e7b

-----Decoded View---------------
Arg [0] : _bank (address): 0x65Fbae61ad2C8836fFbFB502A0dA41b0789D9Fc6
Arg [1] : _tbtcToken (address): 0x18084fbA666a33d37592fA2633fD49a74DD93a88
Arg [2] : _bridge (address): 0x5e4861a80B55f035D899f66772117F00FA0E8e7B

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 00000000000000000000000065fbae61ad2c8836ffbfb502a0da41b0789d9fc6
Arg [1] : 00000000000000000000000018084fba666a33d37592fa2633fd49a74dd93a88
Arg [2] : 0000000000000000000000005e4861a80b55f035d899f66772117f00fa0e8e7b


Block Age Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Age Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Age Amount
View All Withdrawals

Transaction Hash Block Age Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.