Echidna Coverage Report

Files

    Files
    156
    Total Lines
    45560
    Coverage
    58.0%
    2305 / 3918 lines
    Actions
    100.0% lib/chimera/src/Asserts.sol
    Lines covered: 1 / 1 (100.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    pragma solidity ^0.8.0;
    3
    4
    abstract contract Asserts {
    5
        function gt(uint256 a, uint256 b, string memory reason) internal virtual;
    6
    7
        function gte(uint256 a, uint256 b, string memory reason) internal virtual;
    8
    9
        function lt(uint256 a, uint256 b, string memory reason) internal virtual;
    10
    11
        function lte(uint256 a, uint256 b, string memory reason) internal virtual;
    12
    13
        function eq(uint256 a, uint256 b, string memory reason) internal virtual;
    14
    15
        function t(bool b, string memory reason) internal virtual;
    16
    17
        function between(uint256 value, uint256 low, uint256 high) internal virtual returns (uint256);
    18
    19
        function between(int256 value, int256 low, int256 high) internal virtual returns (int256);
    20
    21
        function precondition(bool p) internal virtual;
    22
    }
    23
    0.0% lib/chimera/src/BaseProperties.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    pragma solidity ^0.8.0;
    3
    4
    import {BaseSetup} from "./BaseSetup.sol";
    5
    6
    abstract contract BaseProperties is BaseSetup {}
    7
    0.0% lib/chimera/src/BaseSetup.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    pragma solidity ^0.8.0;
    3
    4
    abstract contract BaseSetup {
    5
        function setup() internal virtual;
    6
    }
    7
    0.0% lib/chimera/src/BaseTargetFunctions.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    pragma solidity ^0.8.0;
    3
    4
    import {BaseProperties} from "./BaseProperties.sol";
    5
    import {Asserts} from "./Asserts.sol";
    6
    7
    abstract contract BaseTargetFunctions is BaseProperties, Asserts {}
    8
    92.0% lib/chimera/src/CryticAsserts.sol
    Lines covered: 13 / 14 (92.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    pragma solidity ^0.8.0;
    3
    4
    import {Asserts} from "./Asserts.sol";
    5
    6
    contract CryticAsserts is Asserts {
    7
        event Log(string);
    8
    9
        function gt(uint256 a, uint256 b, string memory reason) internal virtual override {
    10
            if (!(a > b)) {
    11
                emit Log(reason);
    12
                assert(false);
    13
            }
    14
        }
    15
    16
        function gte(uint256 a, uint256 b, string memory reason) internal virtual override {
    17
            if (!(a >= b)) {
    18
                emit Log(reason);
    19
                assert(false);
    20
            }
    21
        }
    22
    23
        function lt(uint256 a, uint256 b, string memory reason) internal virtual override {
    24
            if (!(a < b)) {
    25
                emit Log(reason);
    26
                assert(false);
    27
            }
    28
        }
    29
    30
        function lte(uint256 a, uint256 b, string memory reason) internal virtual override {
    31
            if (!(a <= b)) {
    32
                emit Log(reason);
    33
                assert(false);
    34
            }
    35
        }
    36
    37
        function eq(uint256 a, uint256 b, string memory reason) internal virtual override {
    38
            if (!(a == b)) {
    39
                emit Log(reason);
    40
                assert(false);
    41
            }
    42
        }
    43
    44
        function t(bool b, string memory reason) internal virtual override {
    45
            if (!b) {
    46
                emit Log(reason);
    47
                assert(false);
    48
            }
    49
        }
    50
    51
        function between(uint256 value, uint256 low, uint256 high) internal virtual override returns (uint256) {
    52
            if (value < low || value > high) {
    53
                uint256 ans = low + (value % (high - low + 1));
    54
                return ans;
    55
            }
    56
            return value;
    57
        }
    58
    59
        function between(int256 value, int256 low, int256 high) internal virtual override returns (int256) {
    60
            if (value < low || value > high) {
    61
                int256 range = high - low + 1;
    62
                int256 clamped = (value - low) % (range);
    63
                if (clamped < 0) clamped += range;
    64
                int256 ans = low + clamped;
    65
                return ans;
    66
            }
    67
            return value;
    68
        }
    69
    70
        function precondition(bool p) internal virtual override {
    71
            require(p);
    72
        }
    73
    }
    74
    0.0% lib/chimera/src/Hevm.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    pragma solidity ^0.8.0;
    3
    4
    // slither-disable-start shadowing-local
    5
    6
    interface IHevm {
    7
        // Set block.timestamp to newTimestamp
    8
        function warp(uint256 newTimestamp) external;
    9
    10
        // Set block.number to newNumber
    11
        function roll(uint256 newNumber) external;
    12
    13
        // Add the condition b to the assumption base for the current branch
    14
        // This function is almost identical to require
    15
        function assume(bool b) external;
    16
    17
        // Sets the eth balance of usr to amt
    18
        function deal(address usr, uint256 amt) external;
    19
    20
        // Loads a storage slot from an address
    21
        function load(address where, bytes32 slot) external returns (bytes32);
    22
    23
        // Stores a value to an address' storage slot
    24
        function store(address where, bytes32 slot, bytes32 value) external;
    25
    26
        // Signs data (privateKey, digest) => (v, r, s)
    27
        function sign(uint256 privateKey, bytes32 digest) external returns (uint8 v, bytes32 r, bytes32 s);
    28
    29
        // Gets address for a given private key
    30
        function addr(uint256 privateKey) external returns (address addr);
    31
    32
        // Performs a foreign function call via terminal
    33
        function ffi(string[] calldata inputs) external returns (bytes memory result);
    34
    35
        // Performs the next smart contract call with specified `msg.sender`
    36
        function prank(address newSender) external;
    37
    38
        // Creates a new fork with the given endpoint and the latest block and returns the identifier of the fork
    39
        function createFork(string calldata urlOrAlias) external returns (uint256);
    40
    41
        // Takes a fork identifier created by createFork and sets the corresponding forked state as active
    42
        function selectFork(uint256 forkId) external;
    43
    44
        // Returns the identifier of the current fork
    45
        function activeFork() external returns (uint256);
    46
    47
        // Labels the address in traces
    48
        function label(address addr, string calldata label) external;
    49
    50
        /// Sets an address' code.
    51
        function etch(address target, bytes calldata newRuntimeBytecode) external;
    52
    }
    53
    54
    IHevm constant vm = IHevm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
    55
    56
    // slither-disable-end shadowing-local
    57
    100.0% lib/forge-std/src/Base.sol
    Lines covered: 1 / 1 (100.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    pragma solidity >=0.6.2 <0.9.0;
    3
    4
    import {StdStorage} from "./StdStorage.sol";
    5
    import {Vm, VmSafe} from "./Vm.sol";
    6
    7
    abstract contract CommonBase {
    8
        /// @dev Cheat code address.
    9
        /// Calculated as `address(uint160(uint256(keccak256("hevm cheat code"))))`.
    10
        address internal constant VM_ADDRESS = 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D;
    11
        /// @dev console.sol and console2.sol work by executing a staticcall to this address.
    12
        /// Calculated as `address(uint160(uint88(bytes11("console.log"))))`.
    13
        address internal constant CONSOLE = 0x000000000000000000636F6e736F6c652e6c6f67;
    14
        /// @dev Used when deploying with create2.
    15
        /// Taken from https://github.com/Arachnid/deterministic-deployment-proxy.
    16
        address internal constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C;
    17
        /// @dev The default address for tx.origin and msg.sender.
    18
        /// Calculated as `address(uint160(uint256(keccak256("foundry default caller"))))`.
    19
        address internal constant DEFAULT_SENDER = 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38;
    20
        /// @dev The address of the first contract `CREATE`d by a running test contract.
    21
        /// When running tests, each test contract is `CREATE`d by `DEFAULT_SENDER` with nonce 1.
    22
        /// Calculated as `VM.computeCreateAddress(VM.computeCreateAddress(DEFAULT_SENDER, 1), 1)`.
    23
        address internal constant DEFAULT_TEST_CONTRACT = 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f;
    24
        /// @dev Deterministic deployment address of the Multicall3 contract.
    25
        /// Taken from https://www.multicall3.com.
    26
        address internal constant MULTICALL3_ADDRESS = 0xcA11bde05977b3631167028862bE2a173976CA11;
    27
        /// @dev The order of the secp256k1 curve.
    28
        uint256 internal constant SECP256K1_ORDER =
    29
            115792089237316195423570985008687907852837564279074904382605163141518161494337;
    30
    31
        uint256 internal constant UINT256_MAX =
    32
            115792089237316195423570985008687907853269984665640564039457584007913129639935;
    33
    34
        Vm internal constant vm = Vm(VM_ADDRESS);
    35
        StdStorage internal stdstore;
    36
    }
    37
    38
    abstract contract TestBase is CommonBase {}
    39
    40
    abstract contract ScriptBase is CommonBase {
    41
        VmSafe internal constant vmSafe = VmSafe(VM_ADDRESS);
    42
    }
    43
    60.0% lib/forge-std/src/StdAssertions.sol
    Lines covered: 3 / 5 (60.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    pragma solidity >=0.6.2 <0.9.0;
    3
    pragma experimental ABIEncoderV2;
    4
    5
    import {Vm} from "./Vm.sol";
    6
    7
    abstract contract StdAssertions {
    8
        Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code")))));
    9
    10
        event log(string);
    11
        event logs(bytes);
    12
    13
        event log_address(address);
    14
        event log_bytes32(bytes32);
    15
        event log_int(int256);
    16
        event log_uint(uint256);
    17
        event log_bytes(bytes);
    18
        event log_string(string);
    19
    20
        event log_named_address(string key, address val);
    21
        event log_named_bytes32(string key, bytes32 val);
    22
        event log_named_decimal_int(string key, int256 val, uint256 decimals);
    23
        event log_named_decimal_uint(string key, uint256 val, uint256 decimals);
    24
        event log_named_int(string key, int256 val);
    25
        event log_named_uint(string key, uint256 val);
    26
        event log_named_bytes(string key, bytes val);
    27
        event log_named_string(string key, string val);
    28
    29
        event log_array(uint256[] val);
    30
        event log_array(int256[] val);
    31
        event log_array(address[] val);
    32
        event log_named_array(string key, uint256[] val);
    33
        event log_named_array(string key, int256[] val);
    34
        event log_named_array(string key, address[] val);
    35
    36
        bool private _failed;
    37
    38
        function failed() public view returns (bool) {
    39
            if (_failed) {
    40
                return _failed;
    41
            } else {
    42
                return vm.load(address(vm), bytes32("failed")) != bytes32(0);
    43
            }
    44
        }
    45
    46
        function fail() internal virtual {
    47
            vm.store(address(vm), bytes32("failed"), bytes32(uint256(1)));
    48
            _failed = true;
    49
        }
    50
    51
        function assertTrue(bool data) internal pure virtual {
    52
            vm.assertTrue(data);
    53
        }
    54
    55
        function assertTrue(bool data, string memory err) internal pure virtual {
    56
            vm.assertTrue(data, err);
    57
        }
    58
    59
        function assertFalse(bool data) internal pure virtual {
    60
            vm.assertFalse(data);
    61
        }
    62
    63
        function assertFalse(bool data, string memory err) internal pure virtual {
    64
            vm.assertFalse(data, err);
    65
        }
    66
    67
        function assertEq(bool left, bool right) internal pure virtual {
    68
            vm.assertEq(left, right);
    69
        }
    70
    71
        function assertEq(bool left, bool right, string memory err) internal pure virtual {
    72
            vm.assertEq(left, right, err);
    73
        }
    74
    75
        function assertEq(uint256 left, uint256 right) internal pure virtual {
    76
            vm.assertEq(left, right);
    77
        }
    78
    79
        function assertEq(uint256 left, uint256 right, string memory err) internal pure virtual {
    80
            vm.assertEq(left, right, err);
    81
        }
    82
    83
        function assertEqDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual {
    84
            vm.assertEqDecimal(left, right, decimals);
    85
        }
    86
    87
        function assertEqDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) internal pure virtual {
    88
            vm.assertEqDecimal(left, right, decimals, err);
    89
        }
    90
    91
        function assertEq(int256 left, int256 right) internal pure virtual {
    92
            vm.assertEq(left, right);
    93
        }
    94
    95
        function assertEq(int256 left, int256 right, string memory err) internal pure virtual {
    96
            vm.assertEq(left, right, err);
    97
        }
    98
    99
        function assertEqDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual {
    100
            vm.assertEqDecimal(left, right, decimals);
    101
        }
    102
    103
        function assertEqDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual {
    104
            vm.assertEqDecimal(left, right, decimals, err);
    105
        }
    106
    107
        function assertEq(address left, address right) internal pure virtual {
    108
            vm.assertEq(left, right);
    109
        }
    110
    111
        function assertEq(address left, address right, string memory err) internal pure virtual {
    112
            vm.assertEq(left, right, err);
    113
        }
    114
    115
        function assertEq(bytes32 left, bytes32 right) internal pure virtual {
    116
            vm.assertEq(left, right);
    117
        }
    118
    119
        function assertEq(bytes32 left, bytes32 right, string memory err) internal pure virtual {
    120
            vm.assertEq(left, right, err);
    121
        }
    122
    123
        function assertEq32(bytes32 left, bytes32 right) internal pure virtual {
    124
            assertEq(left, right);
    125
        }
    126
    127
        function assertEq32(bytes32 left, bytes32 right, string memory err) internal pure virtual {
    128
            assertEq(left, right, err);
    129
        }
    130
    131
        function assertEq(string memory left, string memory right) internal pure virtual {
    132
            vm.assertEq(left, right);
    133
        }
    134
    135
        function assertEq(string memory left, string memory right, string memory err) internal pure virtual {
    136
            vm.assertEq(left, right, err);
    137
        }
    138
    139
        function assertEq(bytes memory left, bytes memory right) internal pure virtual {
    140
            vm.assertEq(left, right);
    141
        }
    142
    143
        function assertEq(bytes memory left, bytes memory right, string memory err) internal pure virtual {
    144
            vm.assertEq(left, right, err);
    145
        }
    146
    147
        function assertEq(bool[] memory left, bool[] memory right) internal pure virtual {
    148
            vm.assertEq(left, right);
    149
        }
    150
    151
        function assertEq(bool[] memory left, bool[] memory right, string memory err) internal pure virtual {
    152
            vm.assertEq(left, right, err);
    153
        }
    154
    155
        function assertEq(uint256[] memory left, uint256[] memory right) internal pure virtual {
    156
            vm.assertEq(left, right);
    157
        }
    158
    159
        function assertEq(uint256[] memory left, uint256[] memory right, string memory err) internal pure virtual {
    160
            vm.assertEq(left, right, err);
    161
        }
    162
    163
        function assertEq(int256[] memory left, int256[] memory right) internal pure virtual {
    164
            vm.assertEq(left, right);
    165
        }
    166
    167
        function assertEq(int256[] memory left, int256[] memory right, string memory err) internal pure virtual {
    168
            vm.assertEq(left, right, err);
    169
        }
    170
    171
        function assertEq(address[] memory left, address[] memory right) internal pure virtual {
    172
            vm.assertEq(left, right);
    173
        }
    174
    175
        function assertEq(address[] memory left, address[] memory right, string memory err) internal pure virtual {
    176
            vm.assertEq(left, right, err);
    177
        }
    178
    179
        function assertEq(bytes32[] memory left, bytes32[] memory right) internal pure virtual {
    180
            vm.assertEq(left, right);
    181
        }
    182
    183
        function assertEq(bytes32[] memory left, bytes32[] memory right, string memory err) internal pure virtual {
    184
            vm.assertEq(left, right, err);
    185
        }
    186
    187
        function assertEq(string[] memory left, string[] memory right) internal pure virtual {
    188
            vm.assertEq(left, right);
    189
        }
    190
    191
        function assertEq(string[] memory left, string[] memory right, string memory err) internal pure virtual {
    192
            vm.assertEq(left, right, err);
    193
        }
    194
    195
        function assertEq(bytes[] memory left, bytes[] memory right) internal pure virtual {
    196
            vm.assertEq(left, right);
    197
        }
    198
    199
        function assertEq(bytes[] memory left, bytes[] memory right, string memory err) internal pure virtual {
    200
            vm.assertEq(left, right, err);
    201
        }
    202
    203
        // Legacy helper
    204
        function assertEqUint(uint256 left, uint256 right) internal pure virtual {
    205
            assertEq(left, right);
    206
        }
    207
    208
        function assertNotEq(bool left, bool right) internal pure virtual {
    209
            vm.assertNotEq(left, right);
    210
        }
    211
    212
        function assertNotEq(bool left, bool right, string memory err) internal pure virtual {
    213
            vm.assertNotEq(left, right, err);
    214
        }
    215
    216
        function assertNotEq(uint256 left, uint256 right) internal pure virtual {
    217
            vm.assertNotEq(left, right);
    218
        }
    219
    220
        function assertNotEq(uint256 left, uint256 right, string memory err) internal pure virtual {
    221
            vm.assertNotEq(left, right, err);
    222
        }
    223
    224
        function assertNotEqDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual {
    225
            vm.assertNotEqDecimal(left, right, decimals);
    226
        }
    227
    228
        function assertNotEqDecimal(uint256 left, uint256 right, uint256 decimals, string memory err)
    229
            internal
    230
            pure
    231
            virtual
    232
        {
    233
            vm.assertNotEqDecimal(left, right, decimals, err);
    234
        }
    235
    236
        function assertNotEq(int256 left, int256 right) internal pure virtual {
    237
            vm.assertNotEq(left, right);
    238
        }
    239
    240
        function assertNotEq(int256 left, int256 right, string memory err) internal pure virtual {
    241
            vm.assertNotEq(left, right, err);
    242
        }
    243
    244
        function assertNotEqDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual {
    245
            vm.assertNotEqDecimal(left, right, decimals);
    246
        }
    247
    248
        function assertNotEqDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual {
    249
            vm.assertNotEqDecimal(left, right, decimals, err);
    250
        }
    251
    252
        function assertNotEq(address left, address right) internal pure virtual {
    253
            vm.assertNotEq(left, right);
    254
        }
    255
    256
        function assertNotEq(address left, address right, string memory err) internal pure virtual {
    257
            vm.assertNotEq(left, right, err);
    258
        }
    259
    260
        function assertNotEq(bytes32 left, bytes32 right) internal pure virtual {
    261
            vm.assertNotEq(left, right);
    262
        }
    263
    264
        function assertNotEq(bytes32 left, bytes32 right, string memory err) internal pure virtual {
    265
            vm.assertNotEq(left, right, err);
    266
        }
    267
    268
        function assertNotEq32(bytes32 left, bytes32 right) internal pure virtual {
    269
            assertNotEq(left, right);
    270
        }
    271
    272
        function assertNotEq32(bytes32 left, bytes32 right, string memory err) internal pure virtual {
    273
            assertNotEq(left, right, err);
    274
        }
    275
    276
        function assertNotEq(string memory left, string memory right) internal pure virtual {
    277
            vm.assertNotEq(left, right);
    278
        }
    279
    280
        function assertNotEq(string memory left, string memory right, string memory err) internal pure virtual {
    281
            vm.assertNotEq(left, right, err);
    282
        }
    283
    284
        function assertNotEq(bytes memory left, bytes memory right) internal pure virtual {
    285
            vm.assertNotEq(left, right);
    286
        }
    287
    288
        function assertNotEq(bytes memory left, bytes memory right, string memory err) internal pure virtual {
    289
            vm.assertNotEq(left, right, err);
    290
        }
    291
    292
        function assertNotEq(bool[] memory left, bool[] memory right) internal pure virtual {
    293
            vm.assertNotEq(left, right);
    294
        }
    295
    296
        function assertNotEq(bool[] memory left, bool[] memory right, string memory err) internal pure virtual {
    297
            vm.assertNotEq(left, right, err);
    298
        }
    299
    300
        function assertNotEq(uint256[] memory left, uint256[] memory right) internal pure virtual {
    301
            vm.assertNotEq(left, right);
    302
        }
    303
    304
        function assertNotEq(uint256[] memory left, uint256[] memory right, string memory err) internal pure virtual {
    305
            vm.assertNotEq(left, right, err);
    306
        }
    307
    308
        function assertNotEq(int256[] memory left, int256[] memory right) internal pure virtual {
    309
            vm.assertNotEq(left, right);
    310
        }
    311
    312
        function assertNotEq(int256[] memory left, int256[] memory right, string memory err) internal pure virtual {
    313
            vm.assertNotEq(left, right, err);
    314
        }
    315
    316
        function assertNotEq(address[] memory left, address[] memory right) internal pure virtual {
    317
            vm.assertNotEq(left, right);
    318
        }
    319
    320
        function assertNotEq(address[] memory left, address[] memory right, string memory err) internal pure virtual {
    321
            vm.assertNotEq(left, right, err);
    322
        }
    323
    324
        function assertNotEq(bytes32[] memory left, bytes32[] memory right) internal pure virtual {
    325
            vm.assertNotEq(left, right);
    326
        }
    327
    328
        function assertNotEq(bytes32[] memory left, bytes32[] memory right, string memory err) internal pure virtual {
    329
            vm.assertNotEq(left, right, err);
    330
        }
    331
    332
        function assertNotEq(string[] memory left, string[] memory right) internal pure virtual {
    333
            vm.assertNotEq(left, right);
    334
        }
    335
    336
        function assertNotEq(string[] memory left, string[] memory right, string memory err) internal pure virtual {
    337
            vm.assertNotEq(left, right, err);
    338
        }
    339
    340
        function assertNotEq(bytes[] memory left, bytes[] memory right) internal pure virtual {
    341
            vm.assertNotEq(left, right);
    342
        }
    343
    344
        function assertNotEq(bytes[] memory left, bytes[] memory right, string memory err) internal pure virtual {
    345
            vm.assertNotEq(left, right, err);
    346
        }
    347
    348
        function assertLt(uint256 left, uint256 right) internal pure virtual {
    349
            vm.assertLt(left, right);
    350
        }
    351
    352
        function assertLt(uint256 left, uint256 right, string memory err) internal pure virtual {
    353
            vm.assertLt(left, right, err);
    354
        }
    355
    356
        function assertLtDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual {
    357
            vm.assertLtDecimal(left, right, decimals);
    358
        }
    359
    360
        function assertLtDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) internal pure virtual {
    361
            vm.assertLtDecimal(left, right, decimals, err);
    362
        }
    363
    364
        function assertLt(int256 left, int256 right) internal pure virtual {
    365
            vm.assertLt(left, right);
    366
        }
    367
    368
        function assertLt(int256 left, int256 right, string memory err) internal pure virtual {
    369
            vm.assertLt(left, right, err);
    370
        }
    371
    372
        function assertLtDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual {
    373
            vm.assertLtDecimal(left, right, decimals);
    374
        }
    375
    376
        function assertLtDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual {
    377
            vm.assertLtDecimal(left, right, decimals, err);
    378
        }
    379
    380
        function assertGt(uint256 left, uint256 right) internal pure virtual {
    381
            vm.assertGt(left, right);
    382
        }
    383
    384
        function assertGt(uint256 left, uint256 right, string memory err) internal pure virtual {
    385
            vm.assertGt(left, right, err);
    386
        }
    387
    388
        function assertGtDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual {
    389
            vm.assertGtDecimal(left, right, decimals);
    390
        }
    391
    392
        function assertGtDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) internal pure virtual {
    393
            vm.assertGtDecimal(left, right, decimals, err);
    394
        }
    395
    396
        function assertGt(int256 left, int256 right) internal pure virtual {
    397
            vm.assertGt(left, right);
    398
        }
    399
    400
        function assertGt(int256 left, int256 right, string memory err) internal pure virtual {
    401
            vm.assertGt(left, right, err);
    402
        }
    403
    404
        function assertGtDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual {
    405
            vm.assertGtDecimal(left, right, decimals);
    406
        }
    407
    408
        function assertGtDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual {
    409
            vm.assertGtDecimal(left, right, decimals, err);
    410
        }
    411
    412
        function assertLe(uint256 left, uint256 right) internal pure virtual {
    413
            vm.assertLe(left, right);
    414
        }
    415
    416
        function assertLe(uint256 left, uint256 right, string memory err) internal pure virtual {
    417
            vm.assertLe(left, right, err);
    418
        }
    419
    420
        function assertLeDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual {
    421
            vm.assertLeDecimal(left, right, decimals);
    422
        }
    423
    424
        function assertLeDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) internal pure virtual {
    425
            vm.assertLeDecimal(left, right, decimals, err);
    426
        }
    427
    428
        function assertLe(int256 left, int256 right) internal pure virtual {
    429
            vm.assertLe(left, right);
    430
        }
    431
    432
        function assertLe(int256 left, int256 right, string memory err) internal pure virtual {
    433
            vm.assertLe(left, right, err);
    434
        }
    435
    436
        function assertLeDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual {
    437
            vm.assertLeDecimal(left, right, decimals);
    438
        }
    439
    440
        function assertLeDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual {
    441
            vm.assertLeDecimal(left, right, decimals, err);
    442
        }
    443
    444
        function assertGe(uint256 left, uint256 right) internal pure virtual {
    445
            vm.assertGe(left, right);
    446
        }
    447
    448
        function assertGe(uint256 left, uint256 right, string memory err) internal pure virtual {
    449
            vm.assertGe(left, right, err);
    450
        }
    451
    452
        function assertGeDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual {
    453
            vm.assertGeDecimal(left, right, decimals);
    454
        }
    455
    456
        function assertGeDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) internal pure virtual {
    457
            vm.assertGeDecimal(left, right, decimals, err);
    458
        }
    459
    460
        function assertGe(int256 left, int256 right) internal pure virtual {
    461
            vm.assertGe(left, right);
    462
        }
    463
    464
        function assertGe(int256 left, int256 right, string memory err) internal pure virtual {
    465
            vm.assertGe(left, right, err);
    466
        }
    467
    468
        function assertGeDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual {
    469
            vm.assertGeDecimal(left, right, decimals);
    470
        }
    471
    472
        function assertGeDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual {
    473
            vm.assertGeDecimal(left, right, decimals, err);
    474
        }
    475
    476
        function assertApproxEqAbs(uint256 left, uint256 right, uint256 maxDelta) internal pure virtual {
    477
            vm.assertApproxEqAbs(left, right, maxDelta);
    478
        }
    479
    480
        function assertApproxEqAbs(uint256 left, uint256 right, uint256 maxDelta, string memory err)
    481
            internal
    482
            pure
    483
            virtual
    484
        {
    485
            vm.assertApproxEqAbs(left, right, maxDelta, err);
    486
        }
    487
    488
        function assertApproxEqAbsDecimal(uint256 left, uint256 right, uint256 maxDelta, uint256 decimals)
    489
            internal
    490
            pure
    491
            virtual
    492
        {
    493
            vm.assertApproxEqAbsDecimal(left, right, maxDelta, decimals);
    494
        }
    495
    496
        function assertApproxEqAbsDecimal(
    497
            uint256 left,
    498
            uint256 right,
    499
            uint256 maxDelta,
    500
            uint256 decimals,
    501
            string memory err
    502
        ) internal pure virtual {
    503
            vm.assertApproxEqAbsDecimal(left, right, maxDelta, decimals, err);
    504
        }
    505
    506
        function assertApproxEqAbs(int256 left, int256 right, uint256 maxDelta) internal pure virtual {
    507
            vm.assertApproxEqAbs(left, right, maxDelta);
    508
        }
    509
    510
        function assertApproxEqAbs(int256 left, int256 right, uint256 maxDelta, string memory err) internal pure virtual {
    511
            vm.assertApproxEqAbs(left, right, maxDelta, err);
    512
        }
    513
    514
        function assertApproxEqAbsDecimal(int256 left, int256 right, uint256 maxDelta, uint256 decimals)
    515
            internal
    516
            pure
    517
            virtual
    518
        {
    519
            vm.assertApproxEqAbsDecimal(left, right, maxDelta, decimals);
    520
        }
    521
    522
        function assertApproxEqAbsDecimal(int256 left, int256 right, uint256 maxDelta, uint256 decimals, string memory err)
    523
            internal
    524
            pure
    525
            virtual
    526
        {
    527
            vm.assertApproxEqAbsDecimal(left, right, maxDelta, decimals, err);
    528
        }
    529
    530
        function assertApproxEqRel(
    531
            uint256 left,
    532
            uint256 right,
    533
            uint256 maxPercentDelta // An 18 decimal fixed point number, where 1e18 == 100%
    534
        ) internal pure virtual {
    535
            vm.assertApproxEqRel(left, right, maxPercentDelta);
    536
        }
    537
    538
        function assertApproxEqRel(
    539
            uint256 left,
    540
            uint256 right,
    541
            uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100%
    542
            string memory err
    543
        ) internal pure virtual {
    544
            vm.assertApproxEqRel(left, right, maxPercentDelta, err);
    545
        }
    546
    547
        function assertApproxEqRelDecimal(
    548
            uint256 left,
    549
            uint256 right,
    550
            uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100%
    551
            uint256 decimals
    552
        ) internal pure virtual {
    553
            vm.assertApproxEqRelDecimal(left, right, maxPercentDelta, decimals);
    554
        }
    555
    556
        function assertApproxEqRelDecimal(
    557
            uint256 left,
    558
            uint256 right,
    559
            uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100%
    560
            uint256 decimals,
    561
            string memory err
    562
        ) internal pure virtual {
    563
            vm.assertApproxEqRelDecimal(left, right, maxPercentDelta, decimals, err);
    564
        }
    565
    566
        function assertApproxEqRel(int256 left, int256 right, uint256 maxPercentDelta) internal pure virtual {
    567
            vm.assertApproxEqRel(left, right, maxPercentDelta);
    568
        }
    569
    570
        function assertApproxEqRel(
    571
            int256 left,
    572
            int256 right,
    573
            uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100%
    574
            string memory err
    575
        ) internal pure virtual {
    576
            vm.assertApproxEqRel(left, right, maxPercentDelta, err);
    577
        }
    578
    579
        function assertApproxEqRelDecimal(
    580
            int256 left,
    581
            int256 right,
    582
            uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100%
    583
            uint256 decimals
    584
        ) internal pure virtual {
    585
            vm.assertApproxEqRelDecimal(left, right, maxPercentDelta, decimals);
    586
        }
    587
    588
        function assertApproxEqRelDecimal(
    589
            int256 left,
    590
            int256 right,
    591
            uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100%
    592
            uint256 decimals,
    593
            string memory err
    594
        ) internal pure virtual {
    595
            vm.assertApproxEqRelDecimal(left, right, maxPercentDelta, decimals, err);
    596
        }
    597
    598
        // Inherited from DSTest, not used but kept for backwards-compatibility
    599
        function checkEq0(bytes memory left, bytes memory right) internal pure returns (bool) {
    600
            return keccak256(left) == keccak256(right);
    601
        }
    602
    603
        function assertEq0(bytes memory left, bytes memory right) internal pure virtual {
    604
            assertEq(left, right);
    605
        }
    606
    607
        function assertEq0(bytes memory left, bytes memory right, string memory err) internal pure virtual {
    608
            assertEq(left, right, err);
    609
        }
    610
    611
        function assertNotEq0(bytes memory left, bytes memory right) internal pure virtual {
    612
            assertNotEq(left, right);
    613
        }
    614
    615
        function assertNotEq0(bytes memory left, bytes memory right, string memory err) internal pure virtual {
    616
            assertNotEq(left, right, err);
    617
        }
    618
    619
        function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB) internal virtual {
    620
            assertEqCall(target, callDataA, target, callDataB, true);
    621
        }
    622
    623
        function assertEqCall(address targetA, bytes memory callDataA, address targetB, bytes memory callDataB)
    624
            internal
    625
            virtual
    626
        {
    627
            assertEqCall(targetA, callDataA, targetB, callDataB, true);
    628
        }
    629
    630
        function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB, bool strictRevertData)
    631
            internal
    632
            virtual
    633
        {
    634
            assertEqCall(target, callDataA, target, callDataB, strictRevertData);
    635
        }
    636
    637
        function assertEqCall(
    638
            address targetA,
    639
            bytes memory callDataA,
    640
            address targetB,
    641
            bytes memory callDataB,
    642
            bool strictRevertData
    643
        ) internal virtual {
    644
            (bool successA, bytes memory returnDataA) = address(targetA).call(callDataA);
    645
            (bool successB, bytes memory returnDataB) = address(targetB).call(callDataB);
    646
    647
            if (successA && successB) {
    648
                assertEq(returnDataA, returnDataB, "Call return data does not match");
    649
            }
    650
    651
            if (!successA && !successB && strictRevertData) {
    652
                assertEq(returnDataA, returnDataB, "Call revert data does not match");
    653
            }
    654
    655
            if (!successA && successB) {
    656
                emit log("Error: Calls were not equal");
    657
                emit log_named_bytes("  Left call revert data", returnDataA);
    658
                emit log_named_bytes(" Right call return data", returnDataB);
    659
                revert("assertion failed");
    660
            }
    661
    662
            if (successA && !successB) {
    663
                emit log("Error: Calls were not equal");
    664
                emit log_named_bytes("  Left call return data", returnDataA);
    665
                emit log_named_bytes(" Right call revert data", returnDataB);
    666
                revert("assertion failed");
    667
            }
    668
        }
    669
    }
    670
    100.0% lib/forge-std/src/StdChains.sol
    Lines covered: 1 / 1 (100.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    pragma solidity >=0.6.2 <0.9.0;
    3
    4
    import {VmSafe} from "./Vm.sol";
    5
    6
    /**
    7
     * StdChains provides information about EVM compatible chains that can be used in scripts/tests.
    8
     * For each chain, the chain's name, chain ID, and a default RPC URL are provided. Chains are
    9
     * identified by their alias, which is the same as the alias in the `[rpc_endpoints]` section of
    10
     * the `foundry.toml` file. For best UX, ensure the alias in the `foundry.toml` file match the
    11
     * alias used in this contract, which can be found as the first argument to the
    12
     * `setChainWithDefaultRpcUrl` call in the `initializeStdChains` function.
    13
     *
    14
     * There are two main ways to use this contract:
    15
     *   1. Set a chain with `setChain(string memory chainAlias, ChainData memory chain)` or
    16
     *      `setChain(string memory chainAlias, Chain memory chain)`
    17
     *   2. Get a chain with `getChain(string memory chainAlias)` or `getChain(uint256 chainId)`.
    18
     *
    19
     * The first time either of those are used, chains are initialized with the default set of RPC URLs.
    20
     * This is done in `initializeStdChains`, which uses `setChainWithDefaultRpcUrl`. Defaults are recorded in
    21
     * `defaultRpcUrls`.
    22
     *
    23
     * The `setChain` function is straightforward, and it simply saves off the given chain data.
    24
     *
    25
     * The `getChain` methods use `getChainWithUpdatedRpcUrl` to return a chain. For example, let's say
    26
     * we want to retrieve the RPC URL for `mainnet`:
    27
     *   - If you have specified data with `setChain`, it will return that.
    28
     *   - If you have configured a mainnet RPC URL in `foundry.toml`, it will return the URL, provided it
    29
     *     is valid (e.g. a URL is specified, or an environment variable is given and exists).
    30
     *   - If neither of the above conditions is met, the default data is returned.
    31
     *
    32
     * Summarizing the above, the prioritization hierarchy is `setChain` -> `foundry.toml` -> environment variable -> defaults.
    33
     */
    34
    abstract contract StdChains {
    35
        VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code")))));
    36
    37
        bool private stdChainsInitialized;
    38
    39
        struct ChainData {
    40
            string name;
    41
            uint256 chainId;
    42
            string rpcUrl;
    43
        }
    44
    45
        struct Chain {
    46
            // The chain name.
    47
            string name;
    48
            // The chain's Chain ID.
    49
            uint256 chainId;
    50
            // The chain's alias. (i.e. what gets specified in `foundry.toml`).
    51
            string chainAlias;
    52
            // A default RPC endpoint for this chain.
    53
            // NOTE: This default RPC URL is included for convenience to facilitate quick tests and
    54
            // experimentation. Do not use this RPC URL for production test suites, CI, or other heavy
    55
            // usage as you will be throttled and this is a disservice to others who need this endpoint.
    56
            string rpcUrl;
    57
        }
    58
    59
        // Maps from the chain's alias (matching the alias in the `foundry.toml` file) to chain data.
    60
        mapping(string => Chain) private chains;
    61
        // Maps from the chain's alias to it's default RPC URL.
    62
        mapping(string => string) private defaultRpcUrls;
    63
        // Maps from a chain ID to it's alias.
    64
        mapping(uint256 => string) private idToAlias;
    65
    66
        bool private fallbackToDefaultRpcUrls = true;
    67
    68
        // The RPC URL will be fetched from config or defaultRpcUrls if possible.
    69
        function getChain(string memory chainAlias) internal virtual returns (Chain memory chain) {
    70
            require(bytes(chainAlias).length != 0, "StdChains getChain(string): Chain alias cannot be the empty string.");
    71
    72
            initializeStdChains();
    73
            chain = chains[chainAlias];
    74
            require(
    75
                chain.chainId != 0,
    76
                string(abi.encodePacked("StdChains getChain(string): Chain with alias \"", chainAlias, "\" not found."))
    77
            );
    78
    79
            chain = getChainWithUpdatedRpcUrl(chainAlias, chain);
    80
        }
    81
    82
        function getChain(uint256 chainId) internal virtual returns (Chain memory chain) {
    83
            require(chainId != 0, "StdChains getChain(uint256): Chain ID cannot be 0.");
    84
            initializeStdChains();
    85
            string memory chainAlias = idToAlias[chainId];
    86
    87
            chain = chains[chainAlias];
    88
    89
            require(
    90
                chain.chainId != 0,
    91
                string(abi.encodePacked("StdChains getChain(uint256): Chain with ID ", vm.toString(chainId), " not found."))
    92
            );
    93
    94
            chain = getChainWithUpdatedRpcUrl(chainAlias, chain);
    95
        }
    96
    97
        // set chain info, with priority to argument's rpcUrl field.
    98
        function setChain(string memory chainAlias, ChainData memory chain) internal virtual {
    99
            require(
    100
                bytes(chainAlias).length != 0,
    101
                "StdChains setChain(string,ChainData): Chain alias cannot be the empty string."
    102
            );
    103
    104
            require(chain.chainId != 0, "StdChains setChain(string,ChainData): Chain ID cannot be 0.");
    105
    106
            initializeStdChains();
    107
            string memory foundAlias = idToAlias[chain.chainId];
    108
    109
            require(
    110
                bytes(foundAlias).length == 0 || keccak256(bytes(foundAlias)) == keccak256(bytes(chainAlias)),
    111
                string(
    112
                    abi.encodePacked(
    113
                        "StdChains setChain(string,ChainData): Chain ID ",
    114
                        vm.toString(chain.chainId),
    115
                        " already used by \"",
    116
                        foundAlias,
    117
                        "\"."
    118
                    )
    119
                )
    120
            );
    121
    122
            uint256 oldChainId = chains[chainAlias].chainId;
    123
            delete idToAlias[oldChainId];
    124
    125
            chains[chainAlias] =
    126
                Chain({name: chain.name, chainId: chain.chainId, chainAlias: chainAlias, rpcUrl: chain.rpcUrl});
    127
            idToAlias[chain.chainId] = chainAlias;
    128
        }
    129
    130
        // set chain info, with priority to argument's rpcUrl field.
    131
        function setChain(string memory chainAlias, Chain memory chain) internal virtual {
    132
            setChain(chainAlias, ChainData({name: chain.name, chainId: chain.chainId, rpcUrl: chain.rpcUrl}));
    133
        }
    134
    135
        function _toUpper(string memory str) private pure returns (string memory) {
    136
            bytes memory strb = bytes(str);
    137
            bytes memory copy = new bytes(strb.length);
    138
            for (uint256 i = 0; i < strb.length; i++) {
    139
                bytes1 b = strb[i];
    140
                if (b >= 0x61 && b <= 0x7A) {
    141
                    copy[i] = bytes1(uint8(b) - 32);
    142
                } else {
    143
                    copy[i] = b;
    144
                }
    145
            }
    146
            return string(copy);
    147
        }
    148
    149
        // lookup rpcUrl, in descending order of priority:
    150
        // current -> config (foundry.toml) -> environment variable -> default
    151
        function getChainWithUpdatedRpcUrl(string memory chainAlias, Chain memory chain)
    152
            private
    153
            view
    154
            returns (Chain memory)
    155
        {
    156
            if (bytes(chain.rpcUrl).length == 0) {
    157
                try vm.rpcUrl(chainAlias) returns (string memory configRpcUrl) {
    158
                    chain.rpcUrl = configRpcUrl;
    159
                } catch (bytes memory err) {
    160
                    string memory envName = string(abi.encodePacked(_toUpper(chainAlias), "_RPC_URL"));
    161
                    if (fallbackToDefaultRpcUrls) {
    162
                        chain.rpcUrl = vm.envOr(envName, defaultRpcUrls[chainAlias]);
    163
                    } else {
    164
                        chain.rpcUrl = vm.envString(envName);
    165
                    }
    166
                    // Distinguish 'not found' from 'cannot read'
    167
                    // The upstream error thrown by forge for failing cheats changed so we check both the old and new versions
    168
                    bytes memory oldNotFoundError =
    169
                        abi.encodeWithSignature("CheatCodeError", string(abi.encodePacked("invalid rpc url ", chainAlias)));
    170
                    bytes memory newNotFoundError = abi.encodeWithSignature(
    171
                        "CheatcodeError(string)", string(abi.encodePacked("invalid rpc url: ", chainAlias))
    172
                    );
    173
                    bytes32 errHash = keccak256(err);
    174
                    if (
    175
                        (errHash != keccak256(oldNotFoundError) && errHash != keccak256(newNotFoundError))
    176
                            || bytes(chain.rpcUrl).length == 0
    177
                    ) {
    178
                        /// @solidity memory-safe-assembly
    179
                        assembly {
    180
                            revert(add(32, err), mload(err))
    181
                        }
    182
                    }
    183
                }
    184
            }
    185
            return chain;
    186
        }
    187
    188
        function setFallbackToDefaultRpcUrls(bool useDefault) internal {
    189
            fallbackToDefaultRpcUrls = useDefault;
    190
        }
    191
    192
        function initializeStdChains() private {
    193
            if (stdChainsInitialized) return;
    194
    195
            stdChainsInitialized = true;
    196
    197
            // If adding an RPC here, make sure to test the default RPC URL in `test_Rpcs` in `StdChains.t.sol`
    198
            setChainWithDefaultRpcUrl("anvil", ChainData("Anvil", 31337, "http://127.0.0.1:8545"));
    199
            setChainWithDefaultRpcUrl("mainnet", ChainData("Mainnet", 1, "https://eth.llamarpc.com"));
    200
            setChainWithDefaultRpcUrl(
    201
                "sepolia", ChainData("Sepolia", 11155111, "https://sepolia.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001")
    202
            );
    203
            setChainWithDefaultRpcUrl("holesky", ChainData("Holesky", 17000, "https://rpc.holesky.ethpandaops.io"));
    204
            setChainWithDefaultRpcUrl("hoodi", ChainData("Hoodi", 560048, "https://rpc.hoodi.ethpandaops.io"));
    205
            setChainWithDefaultRpcUrl("optimism", ChainData("Optimism", 10, "https://mainnet.optimism.io"));
    206
            setChainWithDefaultRpcUrl(
    207
                "optimism_sepolia", ChainData("Optimism Sepolia", 11155420, "https://sepolia.optimism.io")
    208
            );
    209
            setChainWithDefaultRpcUrl("arbitrum_one", ChainData("Arbitrum One", 42161, "https://arb1.arbitrum.io/rpc"));
    210
            setChainWithDefaultRpcUrl(
    211
                "arbitrum_one_sepolia", ChainData("Arbitrum One Sepolia", 421614, "https://sepolia-rollup.arbitrum.io/rpc")
    212
            );
    213
            setChainWithDefaultRpcUrl("arbitrum_nova", ChainData("Arbitrum Nova", 42170, "https://nova.arbitrum.io/rpc"));
    214
            setChainWithDefaultRpcUrl("polygon", ChainData("Polygon", 137, "https://polygon-rpc.com"));
    215
            setChainWithDefaultRpcUrl(
    216
                "polygon_amoy", ChainData("Polygon Amoy", 80002, "https://rpc-amoy.polygon.technology")
    217
            );
    218
            setChainWithDefaultRpcUrl("avalanche", ChainData("Avalanche", 43114, "https://api.avax.network/ext/bc/C/rpc"));
    219
            setChainWithDefaultRpcUrl(
    220
                "avalanche_fuji", ChainData("Avalanche Fuji", 43113, "https://api.avax-test.network/ext/bc/C/rpc")
    221
            );
    222
            setChainWithDefaultRpcUrl(
    223
                "bnb_smart_chain", ChainData("BNB Smart Chain", 56, "https://bsc-dataseed1.binance.org")
    224
            );
    225
            setChainWithDefaultRpcUrl(
    226
                "bnb_smart_chain_testnet",
    227
                ChainData("BNB Smart Chain Testnet", 97, "https://rpc.ankr.com/bsc_testnet_chapel")
    228
            );
    229
            setChainWithDefaultRpcUrl("gnosis_chain", ChainData("Gnosis Chain", 100, "https://rpc.gnosischain.com"));
    230
            setChainWithDefaultRpcUrl("moonbeam", ChainData("Moonbeam", 1284, "https://rpc.api.moonbeam.network"));
    231
            setChainWithDefaultRpcUrl(
    232
                "moonriver", ChainData("Moonriver", 1285, "https://rpc.api.moonriver.moonbeam.network")
    233
            );
    234
            setChainWithDefaultRpcUrl("moonbase", ChainData("Moonbase", 1287, "https://rpc.testnet.moonbeam.network"));
    235
            setChainWithDefaultRpcUrl("base_sepolia", ChainData("Base Sepolia", 84532, "https://sepolia.base.org"));
    236
            setChainWithDefaultRpcUrl("base", ChainData("Base", 8453, "https://mainnet.base.org"));
    237
            setChainWithDefaultRpcUrl("blast_sepolia", ChainData("Blast Sepolia", 168587773, "https://sepolia.blast.io"));
    238
            setChainWithDefaultRpcUrl("blast", ChainData("Blast", 81457, "https://rpc.blast.io"));
    239
            setChainWithDefaultRpcUrl("fantom_opera", ChainData("Fantom Opera", 250, "https://rpc.ankr.com/fantom/"));
    240
            setChainWithDefaultRpcUrl(
    241
                "fantom_opera_testnet", ChainData("Fantom Opera Testnet", 4002, "https://rpc.ankr.com/fantom_testnet/")
    242
            );
    243
            setChainWithDefaultRpcUrl("fraxtal", ChainData("Fraxtal", 252, "https://rpc.frax.com"));
    244
            setChainWithDefaultRpcUrl("fraxtal_testnet", ChainData("Fraxtal Testnet", 2522, "https://rpc.testnet.frax.com"));
    245
            setChainWithDefaultRpcUrl(
    246
                "berachain_bartio_testnet", ChainData("Berachain bArtio Testnet", 80084, "https://bartio.rpc.berachain.com")
    247
            );
    248
            setChainWithDefaultRpcUrl("flare", ChainData("Flare", 14, "https://flare-api.flare.network/ext/C/rpc"));
    249
            setChainWithDefaultRpcUrl(
    250
                "flare_coston2", ChainData("Flare Coston2", 114, "https://coston2-api.flare.network/ext/C/rpc")
    251
            );
    252
    253
            setChainWithDefaultRpcUrl("mode", ChainData("Mode", 34443, "https://mode.drpc.org"));
    254
            setChainWithDefaultRpcUrl("mode_sepolia", ChainData("Mode Sepolia", 919, "https://sepolia.mode.network"));
    255
    256
            setChainWithDefaultRpcUrl("zora", ChainData("Zora", 7777777, "https://zora.drpc.org"));
    257
            setChainWithDefaultRpcUrl(
    258
                "zora_sepolia", ChainData("Zora Sepolia", 999999999, "https://sepolia.rpc.zora.energy")
    259
            );
    260
    261
            setChainWithDefaultRpcUrl("race", ChainData("Race", 6805, "https://racemainnet.io"));
    262
            setChainWithDefaultRpcUrl("race_sepolia", ChainData("Race Sepolia", 6806, "https://racemainnet.io"));
    263
    264
            setChainWithDefaultRpcUrl("metal", ChainData("Metal", 1750, "https://metall2.drpc.org"));
    265
            setChainWithDefaultRpcUrl("metal_sepolia", ChainData("Metal Sepolia", 1740, "https://testnet.rpc.metall2.com"));
    266
    267
            setChainWithDefaultRpcUrl("binary", ChainData("Binary", 624, "https://rpc.zero.thebinaryholdings.com"));
    268
            setChainWithDefaultRpcUrl(
    269
                "binary_sepolia", ChainData("Binary Sepolia", 625, "https://rpc.zero.thebinaryholdings.com")
    270
            );
    271
    272
            setChainWithDefaultRpcUrl("orderly", ChainData("Orderly", 291, "https://rpc.orderly.network"));
    273
            setChainWithDefaultRpcUrl(
    274
                "orderly_sepolia", ChainData("Orderly Sepolia", 4460, "https://testnet-rpc.orderly.org")
    275
            );
    276
        }
    277
    278
        // set chain info, with priority to chainAlias' rpc url in foundry.toml
    279
        function setChainWithDefaultRpcUrl(string memory chainAlias, ChainData memory chain) private {
    280
            string memory rpcUrl = chain.rpcUrl;
    281
            defaultRpcUrls[chainAlias] = rpcUrl;
    282
            chain.rpcUrl = "";
    283
            setChain(chainAlias, chain);
    284
            chain.rpcUrl = rpcUrl; // restore argument
    285
        }
    286
    }
    287
    100.0% lib/forge-std/src/StdCheats.sol
    Lines covered: 6 / 6 (100.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    pragma solidity >=0.6.2 <0.9.0;
    3
    4
    pragma experimental ABIEncoderV2;
    5
    6
    import {StdStorage, stdStorage} from "./StdStorage.sol";
    7
    import {console2} from "./console2.sol";
    8
    import {Vm} from "./Vm.sol";
    9
    10
    abstract contract StdCheatsSafe {
    11
        Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code")))));
    12
    13
        uint256 private constant UINT256_MAX =
    14
            115792089237316195423570985008687907853269984665640564039457584007913129639935;
    15
    16
        bool private gasMeteringOff;
    17
    18
        // Data structures to parse Transaction objects from the broadcast artifact
    19
        // that conform to EIP1559. The Raw structs is what is parsed from the JSON
    20
        // and then converted to the one that is used by the user for better UX.
    21
    22
        struct RawTx1559 {
    23
            string[] arguments;
    24
            address contractAddress;
    25
            string contractName;
    26
            // json value name = function
    27
            string functionSig;
    28
            bytes32 hash;
    29
            // json value name = tx
    30
            RawTx1559Detail txDetail;
    31
            // json value name = type
    32
            string opcode;
    33
        }
    34
    35
        struct RawTx1559Detail {
    36
            AccessList[] accessList;
    37
            bytes data;
    38
            address from;
    39
            bytes gas;
    40
            bytes nonce;
    41
            address to;
    42
            bytes txType;
    43
            bytes value;
    44
        }
    45
    46
        struct Tx1559 {
    47
            string[] arguments;
    48
            address contractAddress;
    49
            string contractName;
    50
            string functionSig;
    51
            bytes32 hash;
    52
            Tx1559Detail txDetail;
    53
            string opcode;
    54
        }
    55
    56
        struct Tx1559Detail {
    57
            AccessList[] accessList;
    58
            bytes data;
    59
            address from;
    60
            uint256 gas;
    61
            uint256 nonce;
    62
            address to;
    63
            uint256 txType;
    64
            uint256 value;
    65
        }
    66
    67
        // Data structures to parse Transaction objects from the broadcast artifact
    68
        // that DO NOT conform to EIP1559. The Raw structs is what is parsed from the JSON
    69
        // and then converted to the one that is used by the user for better UX.
    70
    71
        struct TxLegacy {
    72
            string[] arguments;
    73
            address contractAddress;
    74
            string contractName;
    75
            string functionSig;
    76
            string hash;
    77
            string opcode;
    78
            TxDetailLegacy transaction;
    79
        }
    80
    81
        struct TxDetailLegacy {
    82
            AccessList[] accessList;
    83
            uint256 chainId;
    84
            bytes data;
    85
            address from;
    86
            uint256 gas;
    87
            uint256 gasPrice;
    88
            bytes32 hash;
    89
            uint256 nonce;
    90
            bytes1 opcode;
    91
            bytes32 r;
    92
            bytes32 s;
    93
            uint256 txType;
    94
            address to;
    95
            uint8 v;
    96
            uint256 value;
    97
        }
    98
    99
        struct AccessList {
    100
            address accessAddress;
    101
            bytes32[] storageKeys;
    102
        }
    103
    104
        // Data structures to parse Receipt objects from the broadcast artifact.
    105
        // The Raw structs is what is parsed from the JSON
    106
        // and then converted to the one that is used by the user for better UX.
    107
    108
        struct RawReceipt {
    109
            bytes32 blockHash;
    110
            bytes blockNumber;
    111
            address contractAddress;
    112
            bytes cumulativeGasUsed;
    113
            bytes effectiveGasPrice;
    114
            address from;
    115
            bytes gasUsed;
    116
            RawReceiptLog[] logs;
    117
            bytes logsBloom;
    118
            bytes status;
    119
            address to;
    120
            bytes32 transactionHash;
    121
            bytes transactionIndex;
    122
        }
    123
    124
        struct Receipt {
    125
            bytes32 blockHash;
    126
            uint256 blockNumber;
    127
            address contractAddress;
    128
            uint256 cumulativeGasUsed;
    129
            uint256 effectiveGasPrice;
    130
            address from;
    131
            uint256 gasUsed;
    132
            ReceiptLog[] logs;
    133
            bytes logsBloom;
    134
            uint256 status;
    135
            address to;
    136
            bytes32 transactionHash;
    137
            uint256 transactionIndex;
    138
        }
    139
    140
        // Data structures to parse the entire broadcast artifact, assuming the
    141
        // transactions conform to EIP1559.
    142
    143
        struct EIP1559ScriptArtifact {
    144
            string[] libraries;
    145
            string path;
    146
            string[] pending;
    147
            Receipt[] receipts;
    148
            uint256 timestamp;
    149
            Tx1559[] transactions;
    150
            TxReturn[] txReturns;
    151
        }
    152
    153
        struct RawEIP1559ScriptArtifact {
    154
            string[] libraries;
    155
            string path;
    156
            string[] pending;
    157
            RawReceipt[] receipts;
    158
            TxReturn[] txReturns;
    159
            uint256 timestamp;
    160
            RawTx1559[] transactions;
    161
        }
    162
    163
        struct RawReceiptLog {
    164
            // json value = address
    165
            address logAddress;
    166
            bytes32 blockHash;
    167
            bytes blockNumber;
    168
            bytes data;
    169
            bytes logIndex;
    170
            bool removed;
    171
            bytes32[] topics;
    172
            bytes32 transactionHash;
    173
            bytes transactionIndex;
    174
            bytes transactionLogIndex;
    175
        }
    176
    177
        struct ReceiptLog {
    178
            // json value = address
    179
            address logAddress;
    180
            bytes32 blockHash;
    181
            uint256 blockNumber;
    182
            bytes data;
    183
            uint256 logIndex;
    184
            bytes32[] topics;
    185
            uint256 transactionIndex;
    186
            uint256 transactionLogIndex;
    187
            bool removed;
    188
        }
    189
    190
        struct TxReturn {
    191
            string internalType;
    192
            string value;
    193
        }
    194
    195
        struct Account {
    196
            address addr;
    197
            uint256 key;
    198
        }
    199
    200
        enum AddressType {
    201
            Payable,
    202
            NonPayable,
    203
            ZeroAddress,
    204
            Precompile,
    205
            ForgeAddress
    206
        }
    207
    208
        // Checks that `addr` is not blacklisted by token contracts that have a blacklist.
    209
        function assumeNotBlacklisted(address token, address addr) internal view virtual {
    210
            // Nothing to check if `token` is not a contract.
    211
            uint256 tokenCodeSize;
    212
            assembly {
    213
                tokenCodeSize := extcodesize(token)
    214
            }
    215
            require(tokenCodeSize > 0, "StdCheats assumeNotBlacklisted(address,address): Token address is not a contract.");
    216
    217
            bool success;
    218
            bytes memory returnData;
    219
    220
            // 4-byte selector for `isBlacklisted(address)`, used by USDC.
    221
            (success, returnData) = token.staticcall(abi.encodeWithSelector(0xfe575a87, addr));
    222
            vm.assume(!success || abi.decode(returnData, (bool)) == false);
    223
    224
            // 4-byte selector for `isBlackListed(address)`, used by USDT.
    225
            (success, returnData) = token.staticcall(abi.encodeWithSelector(0xe47d6060, addr));
    226
            vm.assume(!success || abi.decode(returnData, (bool)) == false);
    227
        }
    228
    229
        // Checks that `addr` is not blacklisted by token contracts that have a blacklist.
    230
        // This is identical to `assumeNotBlacklisted(address,address)` but with a different name, for
    231
        // backwards compatibility, since this name was used in the original PR which already has
    232
        // a release. This function can be removed in a future release once we want a breaking change.
    233
        function assumeNoBlacklisted(address token, address addr) internal view virtual {
    234
            assumeNotBlacklisted(token, addr);
    235
        }
    236
    237
        function assumeAddressIsNot(address addr, AddressType addressType) internal virtual {
    238
            if (addressType == AddressType.Payable) {
    239
                assumeNotPayable(addr);
    240
            } else if (addressType == AddressType.NonPayable) {
    241
                assumePayable(addr);
    242
            } else if (addressType == AddressType.ZeroAddress) {
    243
                assumeNotZeroAddress(addr);
    244
            } else if (addressType == AddressType.Precompile) {
    245
                assumeNotPrecompile(addr);
    246
            } else if (addressType == AddressType.ForgeAddress) {
    247
                assumeNotForgeAddress(addr);
    248
            }
    249
        }
    250
    251
        function assumeAddressIsNot(address addr, AddressType addressType1, AddressType addressType2) internal virtual {
    252
            assumeAddressIsNot(addr, addressType1);
    253
            assumeAddressIsNot(addr, addressType2);
    254
        }
    255
    256
        function assumeAddressIsNot(
    257
            address addr,
    258
            AddressType addressType1,
    259
            AddressType addressType2,
    260
            AddressType addressType3
    261
        ) internal virtual {
    262
            assumeAddressIsNot(addr, addressType1);
    263
            assumeAddressIsNot(addr, addressType2);
    264
            assumeAddressIsNot(addr, addressType3);
    265
        }
    266
    267
        function assumeAddressIsNot(
    268
            address addr,
    269
            AddressType addressType1,
    270
            AddressType addressType2,
    271
            AddressType addressType3,
    272
            AddressType addressType4
    273
        ) internal virtual {
    274
            assumeAddressIsNot(addr, addressType1);
    275
            assumeAddressIsNot(addr, addressType2);
    276
            assumeAddressIsNot(addr, addressType3);
    277
            assumeAddressIsNot(addr, addressType4);
    278
        }
    279
    280
        // This function checks whether an address, `addr`, is payable. It works by sending 1 wei to
    281
        // `addr` and checking the `success` return value.
    282
        // NOTE: This function may result in state changes depending on the fallback/receive logic
    283
        // implemented by `addr`, which should be taken into account when this function is used.
    284
        function _isPayable(address addr) private returns (bool) {
    285
            require(
    286
                addr.balance < UINT256_MAX,
    287
                "StdCheats _isPayable(address): Balance equals max uint256, so it cannot receive any more funds"
    288
            );
    289
            uint256 origBalanceTest = address(this).balance;
    290
            uint256 origBalanceAddr = address(addr).balance;
    291
    292
            vm.deal(address(this), 1);
    293
            (bool success,) = payable(addr).call{value: 1}("");
    294
    295
            // reset balances
    296
            vm.deal(address(this), origBalanceTest);
    297
            vm.deal(addr, origBalanceAddr);
    298
    299
            return success;
    300
        }
    301
    302
        // NOTE: This function may result in state changes depending on the fallback/receive logic
    303
        // implemented by `addr`, which should be taken into account when this function is used. See the
    304
        // `_isPayable` method for more information.
    305
        function assumePayable(address addr) internal virtual {
    306
            vm.assume(_isPayable(addr));
    307
        }
    308
    309
        function assumeNotPayable(address addr) internal virtual {
    310
            vm.assume(!_isPayable(addr));
    311
        }
    312
    313
        function assumeNotZeroAddress(address addr) internal pure virtual {
    314
            vm.assume(addr != address(0));
    315
        }
    316
    317
        function assumeNotPrecompile(address addr) internal pure virtual {
    318
            assumeNotPrecompile(addr, _pureChainId());
    319
        }
    320
    321
        function assumeNotPrecompile(address addr, uint256 chainId) internal pure virtual {
    322
            // Note: For some chains like Optimism these are technically predeploys (i.e. bytecode placed at a specific
    323
            // address), but the same rationale for excluding them applies so we include those too.
    324
    325
            // These are reserved by Ethereum and may be on all EVM-compatible chains.
    326
            vm.assume(addr < address(0x1) || addr > address(0xff));
    327
    328
            // forgefmt: disable-start
    329
            if (chainId == 10 || chainId == 420) {
    330
                // https://github.com/ethereum-optimism/optimism/blob/eaa371a0184b56b7ca6d9eb9cb0a2b78b2ccd864/op-bindings/predeploys/addresses.go#L6-L21
    331
                vm.assume(addr < address(0x4200000000000000000000000000000000000000) || addr > address(0x4200000000000000000000000000000000000800));
    332
            } else if (chainId == 42161 || chainId == 421613) {
    333
                // https://developer.arbitrum.io/useful-addresses#arbitrum-precompiles-l2-same-on-all-arb-chains
    334
                vm.assume(addr < address(0x0000000000000000000000000000000000000064) || addr > address(0x0000000000000000000000000000000000000068));
    335
            } else if (chainId == 43114 || chainId == 43113) {
    336
                // https://github.com/ava-labs/subnet-evm/blob/47c03fd007ecaa6de2c52ea081596e0a88401f58/precompile/params.go#L18-L59
    337
                vm.assume(addr < address(0x0100000000000000000000000000000000000000) || addr > address(0x01000000000000000000000000000000000000ff));
    338
                vm.assume(addr < address(0x0200000000000000000000000000000000000000) || addr > address(0x02000000000000000000000000000000000000FF));
    339
                vm.assume(addr < address(0x0300000000000000000000000000000000000000) || addr > address(0x03000000000000000000000000000000000000Ff));
    340
            }
    341
            // forgefmt: disable-end
    342
        }
    343
    344
        function assumeNotForgeAddress(address addr) internal pure virtual {
    345
            // vm, console, and Create2Deployer addresses
    346
            vm.assume(
    347
                addr != address(vm) && addr != 0x000000000000000000636F6e736F6c652e6c6f67
    348
                    && addr != 0x4e59b44847b379578588920cA78FbF26c0B4956C
    349
            );
    350
        }
    351
    352
        function assumeUnusedAddress(address addr) internal view virtual {
    353
            uint256 size;
    354
            assembly {
    355
                size := extcodesize(addr)
    356
            }
    357
            vm.assume(size == 0);
    358
    359
            assumeNotPrecompile(addr);
    360
            assumeNotZeroAddress(addr);
    361
            assumeNotForgeAddress(addr);
    362
        }
    363
    364
        function readEIP1559ScriptArtifact(string memory path)
    365
            internal
    366
            view
    367
            virtual
    368
            returns (EIP1559ScriptArtifact memory)
    369
        {
    370
            string memory data = vm.readFile(path);
    371
            bytes memory parsedData = vm.parseJson(data);
    372
            RawEIP1559ScriptArtifact memory rawArtifact = abi.decode(parsedData, (RawEIP1559ScriptArtifact));
    373
            EIP1559ScriptArtifact memory artifact;
    374
            artifact.libraries = rawArtifact.libraries;
    375
            artifact.path = rawArtifact.path;
    376
            artifact.timestamp = rawArtifact.timestamp;
    377
            artifact.pending = rawArtifact.pending;
    378
            artifact.txReturns = rawArtifact.txReturns;
    379
            artifact.receipts = rawToConvertedReceipts(rawArtifact.receipts);
    380
            artifact.transactions = rawToConvertedEIPTx1559s(rawArtifact.transactions);
    381
            return artifact;
    382
        }
    383
    384
        function rawToConvertedEIPTx1559s(RawTx1559[] memory rawTxs) internal pure virtual returns (Tx1559[] memory) {
    385
            Tx1559[] memory txs = new Tx1559[](rawTxs.length);
    386
            for (uint256 i; i < rawTxs.length; i++) {
    387
                txs[i] = rawToConvertedEIPTx1559(rawTxs[i]);
    388
            }
    389
            return txs;
    390
        }
    391
    392
        function rawToConvertedEIPTx1559(RawTx1559 memory rawTx) internal pure virtual returns (Tx1559 memory) {
    393
            Tx1559 memory transaction;
    394
            transaction.arguments = rawTx.arguments;
    395
            transaction.contractName = rawTx.contractName;
    396
            transaction.functionSig = rawTx.functionSig;
    397
            transaction.hash = rawTx.hash;
    398
            transaction.txDetail = rawToConvertedEIP1559Detail(rawTx.txDetail);
    399
            transaction.opcode = rawTx.opcode;
    400
            return transaction;
    401
        }
    402
    403
        function rawToConvertedEIP1559Detail(RawTx1559Detail memory rawDetail)
    404
            internal
    405
            pure
    406
            virtual
    407
            returns (Tx1559Detail memory)
    408
        {
    409
            Tx1559Detail memory txDetail;
    410
            txDetail.data = rawDetail.data;
    411
            txDetail.from = rawDetail.from;
    412
            txDetail.to = rawDetail.to;
    413
            txDetail.nonce = _bytesToUint(rawDetail.nonce);
    414
            txDetail.txType = _bytesToUint(rawDetail.txType);
    415
            txDetail.value = _bytesToUint(rawDetail.value);
    416
            txDetail.gas = _bytesToUint(rawDetail.gas);
    417
            txDetail.accessList = rawDetail.accessList;
    418
            return txDetail;
    419
        }
    420
    421
        function readTx1559s(string memory path) internal view virtual returns (Tx1559[] memory) {
    422
            string memory deployData = vm.readFile(path);
    423
            bytes memory parsedDeployData = vm.parseJson(deployData, ".transactions");
    424
            RawTx1559[] memory rawTxs = abi.decode(parsedDeployData, (RawTx1559[]));
    425
            return rawToConvertedEIPTx1559s(rawTxs);
    426
        }
    427
    428
        function readTx1559(string memory path, uint256 index) internal view virtual returns (Tx1559 memory) {
    429
            string memory deployData = vm.readFile(path);
    430
            string memory key = string(abi.encodePacked(".transactions[", vm.toString(index), "]"));
    431
            bytes memory parsedDeployData = vm.parseJson(deployData, key);
    432
            RawTx1559 memory rawTx = abi.decode(parsedDeployData, (RawTx1559));
    433
            return rawToConvertedEIPTx1559(rawTx);
    434
        }
    435
    436
        // Analogous to readTransactions, but for receipts.
    437
        function readReceipts(string memory path) internal view virtual returns (Receipt[] memory) {
    438
            string memory deployData = vm.readFile(path);
    439
            bytes memory parsedDeployData = vm.parseJson(deployData, ".receipts");
    440
            RawReceipt[] memory rawReceipts = abi.decode(parsedDeployData, (RawReceipt[]));
    441
            return rawToConvertedReceipts(rawReceipts);
    442
        }
    443
    444
        function readReceipt(string memory path, uint256 index) internal view virtual returns (Receipt memory) {
    445
            string memory deployData = vm.readFile(path);
    446
            string memory key = string(abi.encodePacked(".receipts[", vm.toString(index), "]"));
    447
            bytes memory parsedDeployData = vm.parseJson(deployData, key);
    448
            RawReceipt memory rawReceipt = abi.decode(parsedDeployData, (RawReceipt));
    449
            return rawToConvertedReceipt(rawReceipt);
    450
        }
    451
    452
        function rawToConvertedReceipts(RawReceipt[] memory rawReceipts) internal pure virtual returns (Receipt[] memory) {
    453
            Receipt[] memory receipts = new Receipt[](rawReceipts.length);
    454
            for (uint256 i; i < rawReceipts.length; i++) {
    455
                receipts[i] = rawToConvertedReceipt(rawReceipts[i]);
    456
            }
    457
            return receipts;
    458
        }
    459
    460
        function rawToConvertedReceipt(RawReceipt memory rawReceipt) internal pure virtual returns (Receipt memory) {
    461
            Receipt memory receipt;
    462
            receipt.blockHash = rawReceipt.blockHash;
    463
            receipt.to = rawReceipt.to;
    464
            receipt.from = rawReceipt.from;
    465
            receipt.contractAddress = rawReceipt.contractAddress;
    466
            receipt.effectiveGasPrice = _bytesToUint(rawReceipt.effectiveGasPrice);
    467
            receipt.cumulativeGasUsed = _bytesToUint(rawReceipt.cumulativeGasUsed);
    468
            receipt.gasUsed = _bytesToUint(rawReceipt.gasUsed);
    469
            receipt.status = _bytesToUint(rawReceipt.status);
    470
            receipt.transactionIndex = _bytesToUint(rawReceipt.transactionIndex);
    471
            receipt.blockNumber = _bytesToUint(rawReceipt.blockNumber);
    472
            receipt.logs = rawToConvertedReceiptLogs(rawReceipt.logs);
    473
            receipt.logsBloom = rawReceipt.logsBloom;
    474
            receipt.transactionHash = rawReceipt.transactionHash;
    475
            return receipt;
    476
        }
    477
    478
        function rawToConvertedReceiptLogs(RawReceiptLog[] memory rawLogs)
    479
            internal
    480
            pure
    481
            virtual
    482
            returns (ReceiptLog[] memory)
    483
        {
    484
            ReceiptLog[] memory logs = new ReceiptLog[](rawLogs.length);
    485
            for (uint256 i; i < rawLogs.length; i++) {
    486
                logs[i].logAddress = rawLogs[i].logAddress;
    487
                logs[i].blockHash = rawLogs[i].blockHash;
    488
                logs[i].blockNumber = _bytesToUint(rawLogs[i].blockNumber);
    489
                logs[i].data = rawLogs[i].data;
    490
                logs[i].logIndex = _bytesToUint(rawLogs[i].logIndex);
    491
                logs[i].topics = rawLogs[i].topics;
    492
                logs[i].transactionIndex = _bytesToUint(rawLogs[i].transactionIndex);
    493
                logs[i].transactionLogIndex = _bytesToUint(rawLogs[i].transactionLogIndex);
    494
                logs[i].removed = rawLogs[i].removed;
    495
            }
    496
            return logs;
    497
        }
    498
    499
        // Deploy a contract by fetching the contract bytecode from
    500
        // the artifacts directory
    501
        // e.g. `deployCode(code, abi.encode(arg1,arg2,arg3))`
    502
        function deployCode(string memory what, bytes memory args) internal virtual returns (address addr) {
    503
            bytes memory bytecode = abi.encodePacked(vm.getCode(what), args);
    504
            /// @solidity memory-safe-assembly
    505
            assembly {
    506
                addr := create(0, add(bytecode, 0x20), mload(bytecode))
    507
            }
    508
    509
            require(addr != address(0), "StdCheats deployCode(string,bytes): Deployment failed.");
    510
        }
    511
    512
        function deployCode(string memory what) internal virtual returns (address addr) {
    513
            bytes memory bytecode = vm.getCode(what);
    514
            /// @solidity memory-safe-assembly
    515
            assembly {
    516
                addr := create(0, add(bytecode, 0x20), mload(bytecode))
    517
            }
    518
    519
            require(addr != address(0), "StdCheats deployCode(string): Deployment failed.");
    520
        }
    521
    522
        /// @dev deploy contract with value on construction
    523
        function deployCode(string memory what, bytes memory args, uint256 val) internal virtual returns (address addr) {
    524
            bytes memory bytecode = abi.encodePacked(vm.getCode(what), args);
    525
            /// @solidity memory-safe-assembly
    526
            assembly {
    527
                addr := create(val, add(bytecode, 0x20), mload(bytecode))
    528
            }
    529
    530
            require(addr != address(0), "StdCheats deployCode(string,bytes,uint256): Deployment failed.");
    531
        }
    532
    533
        function deployCode(string memory what, uint256 val) internal virtual returns (address addr) {
    534
            bytes memory bytecode = vm.getCode(what);
    535
            /// @solidity memory-safe-assembly
    536
            assembly {
    537
                addr := create(val, add(bytecode, 0x20), mload(bytecode))
    538
            }
    539
    540
            require(addr != address(0), "StdCheats deployCode(string,uint256): Deployment failed.");
    541
        }
    542
    543
        // creates a labeled address and the corresponding private key
    544
        function makeAddrAndKey(string memory name) internal virtual returns (address addr, uint256 privateKey) {
    545
            privateKey = uint256(keccak256(abi.encodePacked(name)));
    546
            addr = vm.addr(privateKey);
    547
            vm.label(addr, name);
    548
        }
    549
    550
        // creates a labeled address
    551
        function makeAddr(string memory name) internal virtual returns (address addr) {
    552
            (addr,) = makeAddrAndKey(name);
    553
        }
    554
    555
        // Destroys an account immediately, sending the balance to beneficiary.
    556
        // Destroying means: balance will be zero, code will be empty, and nonce will be 0
    557
        // This is similar to selfdestruct but not identical: selfdestruct destroys code and nonce
    558
        // only after tx ends, this will run immediately.
    559
        function destroyAccount(address who, address beneficiary) internal virtual {
    560
            uint256 currBalance = who.balance;
    561
            vm.etch(who, abi.encode());
    562
            vm.deal(who, 0);
    563
            vm.resetNonce(who);
    564
    565
            uint256 beneficiaryBalance = beneficiary.balance;
    566
            vm.deal(beneficiary, currBalance + beneficiaryBalance);
    567
        }
    568
    569
        // creates a struct containing both a labeled address and the corresponding private key
    570
        function makeAccount(string memory name) internal virtual returns (Account memory account) {
    571
            (account.addr, account.key) = makeAddrAndKey(name);
    572
        }
    573
    574
        function deriveRememberKey(string memory mnemonic, uint32 index)
    575
            internal
    576
            virtual
    577
            returns (address who, uint256 privateKey)
    578
        {
    579
            privateKey = vm.deriveKey(mnemonic, index);
    580
            who = vm.rememberKey(privateKey);
    581
        }
    582
    583
        function _bytesToUint(bytes memory b) private pure returns (uint256) {
    584
            require(b.length <= 32, "StdCheats _bytesToUint(bytes): Bytes length exceeds 32.");
    585
            return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256));
    586
        }
    587
    588
        function isFork() internal view virtual returns (bool status) {
    589
            try vm.activeFork() {
    590
                status = true;
    591
            } catch (bytes memory) {}
    592
        }
    593
    594
        modifier skipWhenForking() {
    595
            if (!isFork()) {
    596
                _;
    597
            }
    598
        }
    599
    600
        modifier skipWhenNotForking() {
    601
            if (isFork()) {
    602
                _;
    603
            }
    604
        }
    605
    606
        modifier noGasMetering() {
    607
            vm.pauseGasMetering();
    608
            // To prevent turning gas monitoring back on with nested functions that use this modifier,
    609
            // we check if gasMetering started in the off position. If it did, we don't want to turn
    610
            // it back on until we exit the top level function that used the modifier
    611
            //
    612
            // i.e. funcA() noGasMetering { funcB() }, where funcB has noGasMetering as well.
    613
            // funcA will have `gasStartedOff` as false, funcB will have it as true,
    614
            // so we only turn metering back on at the end of the funcA
    615
            bool gasStartedOff = gasMeteringOff;
    616
            gasMeteringOff = true;
    617
    618
            _;
    619
    620
            // if gas metering was on when this modifier was called, turn it back on at the end
    621
            if (!gasStartedOff) {
    622
                gasMeteringOff = false;
    623
                vm.resumeGasMetering();
    624
            }
    625
        }
    626
    627
        // We use this complex approach of `_viewChainId` and `_pureChainId` to ensure there are no
    628
        // compiler warnings when accessing chain ID in any solidity version supported by forge-std. We
    629
        // can't simply access the chain ID in a normal view or pure function because the solc View Pure
    630
        // Checker changed `chainid` from pure to view in 0.8.0.
    631
        function _viewChainId() private view returns (uint256 chainId) {
    632
            // Assembly required since `block.chainid` was introduced in 0.8.0.
    633
            assembly {
    634
                chainId := chainid()
    635
            }
    636
    637
            address(this); // Silence warnings in older Solc versions.
    638
        }
    639
    640
        function _pureChainId() private pure returns (uint256 chainId) {
    641
            function() internal view returns (uint256) fnIn = _viewChainId;
    642
            function() internal pure returns (uint256) pureChainId;
    643
            assembly {
    644
                pureChainId := fnIn
    645
            }
    646
            chainId = pureChainId();
    647
        }
    648
    }
    649
    650
    // Wrappers around cheatcodes to avoid footguns
    651
    abstract contract StdCheats is StdCheatsSafe {
    652
        using stdStorage for StdStorage;
    653
    654
        StdStorage private stdstore;
    655
        Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code")))));
    656
        address private constant CONSOLE2_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67;
    657
    658
        // Skip forward or rewind time by the specified number of seconds
    659
        function skip(uint256 time) internal virtual {
    660
            vm.warp(vm.getBlockTimestamp() + time);
    661
        }
    662
    663
        function rewind(uint256 time) internal virtual {
    664
            vm.warp(vm.getBlockTimestamp() - time);
    665
        }
    666
    667
        // Setup a prank from an address that has some ether
    668
        function hoax(address msgSender) internal virtual {
    669
            vm.deal(msgSender, 1 << 128);
    670
            vm.prank(msgSender);
    671
        }
    672
    673
        function hoax(address msgSender, uint256 give) internal virtual {
    674
            vm.deal(msgSender, give);
    675
            vm.prank(msgSender);
    676
        }
    677
    678
        function hoax(address msgSender, address origin) internal virtual {
    679
            vm.deal(msgSender, 1 << 128);
    680
            vm.prank(msgSender, origin);
    681
        }
    682
    683
        function hoax(address msgSender, address origin, uint256 give) internal virtual {
    684
            vm.deal(msgSender, give);
    685
            vm.prank(msgSender, origin);
    686
        }
    687
    688
        // Start perpetual prank from an address that has some ether
    689
        function startHoax(address msgSender) internal virtual {
    690
            vm.deal(msgSender, 1 << 128);
    691
            vm.startPrank(msgSender);
    692
        }
    693
    694
        function startHoax(address msgSender, uint256 give) internal virtual {
    695
            vm.deal(msgSender, give);
    696
            vm.startPrank(msgSender);
    697
        }
    698
    699
        // Start perpetual prank from an address that has some ether
    700
        // tx.origin is set to the origin parameter
    701
        function startHoax(address msgSender, address origin) internal virtual {
    702
            vm.deal(msgSender, 1 << 128);
    703
            vm.startPrank(msgSender, origin);
    704
        }
    705
    706
        function startHoax(address msgSender, address origin, uint256 give) internal virtual {
    707
            vm.deal(msgSender, give);
    708
            vm.startPrank(msgSender, origin);
    709
        }
    710
    711
        function changePrank(address msgSender) internal virtual {
    712
            console2_log_StdCheats("changePrank is deprecated. Please use vm.startPrank instead.");
    713
            vm.stopPrank();
    714
            vm.startPrank(msgSender);
    715
        }
    716
    717
        function changePrank(address msgSender, address txOrigin) internal virtual {
    718
            vm.stopPrank();
    719
            vm.startPrank(msgSender, txOrigin);
    720
        }
    721
    722
        // The same as Vm's `deal`
    723
        // Use the alternative signature for ERC20 tokens
    724
        function deal(address to, uint256 give) internal virtual {
    725
            vm.deal(to, give);
    726
        }
    727
    728
        // Set the balance of an account for any ERC20 token
    729
        // Use the alternative signature to update `totalSupply`
    730
        function deal(address token, address to, uint256 give) internal virtual {
    731
            deal(token, to, give, false);
    732
        }
    733
    734
        // Set the balance of an account for any ERC1155 token
    735
        // Use the alternative signature to update `totalSupply`
    736
        function dealERC1155(address token, address to, uint256 id, uint256 give) internal virtual {
    737
            dealERC1155(token, to, id, give, false);
    738
        }
    739
    740
        function deal(address token, address to, uint256 give, bool adjust) internal virtual {
    741
            // get current balance
    742
            (, bytes memory balData) = token.staticcall(abi.encodeWithSelector(0x70a08231, to));
    743
            uint256 prevBal = abi.decode(balData, (uint256));
    744
    745
            // update balance
    746
            stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(give);
    747
    748
            // update total supply
    749
            if (adjust) {
    750
                (, bytes memory totSupData) = token.staticcall(abi.encodeWithSelector(0x18160ddd));
    751
                uint256 totSup = abi.decode(totSupData, (uint256));
    752
                if (give < prevBal) {
    753
                    totSup -= (prevBal - give);
    754
                } else {
    755
                    totSup += (give - prevBal);
    756
                }
    757
                stdstore.target(token).sig(0x18160ddd).checked_write(totSup);
    758
            }
    759
        }
    760
    761
        function dealERC1155(address token, address to, uint256 id, uint256 give, bool adjust) internal virtual {
    762
            // get current balance
    763
            (, bytes memory balData) = token.staticcall(abi.encodeWithSelector(0x00fdd58e, to, id));
    764
            uint256 prevBal = abi.decode(balData, (uint256));
    765
    766
            // update balance
    767
            stdstore.target(token).sig(0x00fdd58e).with_key(to).with_key(id).checked_write(give);
    768
    769
            // update total supply
    770
            if (adjust) {
    771
                (, bytes memory totSupData) = token.staticcall(abi.encodeWithSelector(0xbd85b039, id));
    772
                require(
    773
                    totSupData.length != 0,
    774
                    "StdCheats deal(address,address,uint,uint,bool): target contract is not ERC1155Supply."
    775
                );
    776
                uint256 totSup = abi.decode(totSupData, (uint256));
    777
                if (give < prevBal) {
    778
                    totSup -= (prevBal - give);
    779
                } else {
    780
                    totSup += (give - prevBal);
    781
                }
    782
                stdstore.target(token).sig(0xbd85b039).with_key(id).checked_write(totSup);
    783
            }
    784
        }
    785
    786
        function dealERC721(address token, address to, uint256 id) internal virtual {
    787
            // check if token id is already minted and the actual owner.
    788
            (bool successMinted, bytes memory ownerData) = token.staticcall(abi.encodeWithSelector(0x6352211e, id));
    789
            require(successMinted, "StdCheats deal(address,address,uint,bool): id not minted.");
    790
    791
            // get owner current balance
    792
            (, bytes memory fromBalData) =
    793
                token.staticcall(abi.encodeWithSelector(0x70a08231, abi.decode(ownerData, (address))));
    794
            uint256 fromPrevBal = abi.decode(fromBalData, (uint256));
    795
    796
            // get new user current balance
    797
            (, bytes memory toBalData) = token.staticcall(abi.encodeWithSelector(0x70a08231, to));
    798
            uint256 toPrevBal = abi.decode(toBalData, (uint256));
    799
    800
            // update balances
    801
            stdstore.target(token).sig(0x70a08231).with_key(abi.decode(ownerData, (address))).checked_write(--fromPrevBal);
    802
            stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(++toPrevBal);
    803
    804
            // update owner
    805
            stdstore.target(token).sig(0x6352211e).with_key(id).checked_write(to);
    806
        }
    807
    808
        function deployCodeTo(string memory what, address where) internal virtual {
    809
            deployCodeTo(what, "", 0, where);
    810
        }
    811
    812
        function deployCodeTo(string memory what, bytes memory args, address where) internal virtual {
    813
            deployCodeTo(what, args, 0, where);
    814
        }
    815
    816
        function deployCodeTo(string memory what, bytes memory args, uint256 value, address where) internal virtual {
    817
            bytes memory creationCode = vm.getCode(what);
    818
            vm.etch(where, abi.encodePacked(creationCode, args));
    819
            (bool success, bytes memory runtimeBytecode) = where.call{value: value}("");
    820
            require(success, "StdCheats deployCodeTo(string,bytes,uint256,address): Failed to create runtime bytecode.");
    821
            vm.etch(where, runtimeBytecode);
    822
        }
    823
    824
        // Used to prevent the compilation of console, which shortens the compilation time when console is not used elsewhere.
    825
        function console2_log_StdCheats(string memory p0) private view {
    826
            (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature("log(string)", p0));
    827
            status;
    828
        }
    829
    }
    830
    100.0% lib/forge-std/src/StdConstants.sol
    Lines covered: 1 / 1 (100.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    pragma solidity >=0.6.2 <0.9.0;
    3
    4
    import {IMulticall3} from "./interfaces/IMulticall3.sol";
    5
    import {Vm} from "./Vm.sol";
    6
    7
    library StdConstants {
    8
        /// @dev Cheat code address.
    9
        /// Calculated as `address(uint160(uint256(keccak256("hevm cheat code"))))`.
    10
        Vm internal constant VM = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
    11
        /// @dev console.sol and console2.sol work by executing a staticcall to this address.
    12
        /// Calculated as `address(uint160(uint88(bytes11("console.log"))))`.
    13
        address internal constant CONSOLE = 0x000000000000000000636F6e736F6c652e6c6f67;
    14
        /// @dev Used when deploying with create2.
    15
        /// Taken from https://github.com/Arachnid/deterministic-deployment-proxy.
    16
        address internal constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C;
    17
        /// @dev The default address for tx.origin and msg.sender.
    18
        /// Calculated as `address(uint160(uint256(keccak256("foundry default caller"))))`.
    19
        address internal constant DEFAULT_SENDER = 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38;
    20
        /// @dev The address of the first contract `CREATE`d by a running test contract.
    21
        /// When running tests, each test contract is `CREATE`d by `DEFAULT_SENDER` with nonce 1.
    22
        /// Calculated as `VM.computeCreateAddress(VM.computeCreateAddress(DEFAULT_SENDER, 1), 1)`.
    23
        address internal constant DEFAULT_TEST_CONTRACT = 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f;
    24
        /// @dev Deterministic deployment address of the Multicall3 contract.
    25
        /// Taken from https://www.multicall3.com.
    26
        IMulticall3 internal constant MULTICALL3_ADDRESS = IMulticall3(0xcA11bde05977b3631167028862bE2a173976CA11);
    27
        /// @dev The order of the secp256k1 curve.
    28
        uint256 internal constant SECP256K1_ORDER =
    29
            115792089237316195423570985008687907852837564279074904382605163141518161494337;
    30
    }
    31
    0.0% lib/forge-std/src/StdError.sol
    Lines covered: 0 / 10 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // Panics work for versions >=0.8.0, but we lowered the pragma to make this compatible with Test
    3
    pragma solidity >=0.6.2 <0.9.0;
    4
    5
    library stdError {
    6
        bytes public constant assertionError = abi.encodeWithSignature("Panic(uint256)", 0x01);
    7
        bytes public constant arithmeticError = abi.encodeWithSignature("Panic(uint256)", 0x11);
    8
        bytes public constant divisionError = abi.encodeWithSignature("Panic(uint256)", 0x12);
    9
        bytes public constant enumConversionError = abi.encodeWithSignature("Panic(uint256)", 0x21);
    10
        bytes public constant encodeStorageError = abi.encodeWithSignature("Panic(uint256)", 0x22);
    11
        bytes public constant popError = abi.encodeWithSignature("Panic(uint256)", 0x31);
    12
        bytes public constant indexOOBError = abi.encodeWithSignature("Panic(uint256)", 0x32);
    13
        bytes public constant memOverflowError = abi.encodeWithSignature("Panic(uint256)", 0x41);
    14
        bytes public constant zeroVarError = abi.encodeWithSignature("Panic(uint256)", 0x51);
    15
    }
    16
    100.0% lib/forge-std/src/StdInvariant.sol
    Lines covered: 20 / 20 (100.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    pragma solidity >=0.6.2 <0.9.0;
    3
    4
    pragma experimental ABIEncoderV2;
    5
    6
    abstract contract StdInvariant {
    7
        struct FuzzSelector {
    8
            address addr;
    9
            bytes4[] selectors;
    10
        }
    11
    12
        struct FuzzArtifactSelector {
    13
            string artifact;
    14
            bytes4[] selectors;
    15
        }
    16
    17
        struct FuzzInterface {
    18
            address addr;
    19
            string[] artifacts;
    20
        }
    21
    22
        address[] private _excludedContracts;
    23
        address[] private _excludedSenders;
    24
        address[] private _targetedContracts;
    25
        address[] private _targetedSenders;
    26
    27
        string[] private _excludedArtifacts;
    28
        string[] private _targetedArtifacts;
    29
    30
        FuzzArtifactSelector[] private _targetedArtifactSelectors;
    31
    32
        FuzzSelector[] private _excludedSelectors;
    33
        FuzzSelector[] private _targetedSelectors;
    34
    35
        FuzzInterface[] private _targetedInterfaces;
    36
    37
        // Functions for users:
    38
        // These are intended to be called in tests.
    39
    40
        function excludeContract(address newExcludedContract_) internal {
    41
            _excludedContracts.push(newExcludedContract_);
    42
        }
    43
    44
        function excludeSelector(FuzzSelector memory newExcludedSelector_) internal {
    45
            _excludedSelectors.push(newExcludedSelector_);
    46
        }
    47
    48
        function excludeSender(address newExcludedSender_) internal {
    49
            _excludedSenders.push(newExcludedSender_);
    50
        }
    51
    52
        function excludeArtifact(string memory newExcludedArtifact_) internal {
    53
            _excludedArtifacts.push(newExcludedArtifact_);
    54
        }
    55
    56
        function targetArtifact(string memory newTargetedArtifact_) internal {
    57
            _targetedArtifacts.push(newTargetedArtifact_);
    58
        }
    59
    60
        function targetArtifactSelector(FuzzArtifactSelector memory newTargetedArtifactSelector_) internal {
    61
            _targetedArtifactSelectors.push(newTargetedArtifactSelector_);
    62
        }
    63
    64
        function targetContract(address newTargetedContract_) internal {
    65
            _targetedContracts.push(newTargetedContract_);
    66
        }
    67
    68
        function targetSelector(FuzzSelector memory newTargetedSelector_) internal {
    69
            _targetedSelectors.push(newTargetedSelector_);
    70
        }
    71
    72
        function targetSender(address newTargetedSender_) internal {
    73
            _targetedSenders.push(newTargetedSender_);
    74
        }
    75
    76
        function targetInterface(FuzzInterface memory newTargetedInterface_) internal {
    77
            _targetedInterfaces.push(newTargetedInterface_);
    78
        }
    79
    80
        // Functions for forge:
    81
        // These are called by forge to run invariant tests and don't need to be called in tests.
    82
    83
        function excludeArtifacts() public view returns (string[] memory excludedArtifacts_) {
    84
            excludedArtifacts_ = _excludedArtifacts;
    85
        }
    86
    87
        function excludeContracts() public view returns (address[] memory excludedContracts_) {
    88
            excludedContracts_ = _excludedContracts;
    89
        }
    90
    91
        function excludeSelectors() public view returns (FuzzSelector[] memory excludedSelectors_) {
    92
            excludedSelectors_ = _excludedSelectors;
    93
        }
    94
    95
        function excludeSenders() public view returns (address[] memory excludedSenders_) {
    96
            excludedSenders_ = _excludedSenders;
    97
        }
    98
    99
        function targetArtifacts() public view returns (string[] memory targetedArtifacts_) {
    100
            targetedArtifacts_ = _targetedArtifacts;
    101
        }
    102
    103
        function targetArtifactSelectors() public view returns (FuzzArtifactSelector[] memory targetedArtifactSelectors_) {
    104
            targetedArtifactSelectors_ = _targetedArtifactSelectors;
    105
        }
    106
    107
        function targetContracts() public view returns (address[] memory targetedContracts_) {
    108
            targetedContracts_ = _targetedContracts;
    109
        }
    110
    111
        function targetSelectors() public view returns (FuzzSelector[] memory targetedSelectors_) {
    112
            targetedSelectors_ = _targetedSelectors;
    113
        }
    114
    115
        function targetSenders() public view returns (address[] memory targetedSenders_) {
    116
            targetedSenders_ = _targetedSenders;
    117
        }
    118
    119
        function targetInterfaces() public view returns (FuzzInterface[] memory targetedInterfaces_) {
    120
            targetedInterfaces_ = _targetedInterfaces;
    121
        }
    122
    }
    123
    100.0% lib/forge-std/src/StdJson.sol
    Lines covered: 1 / 1 (100.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    pragma solidity >=0.6.0 <0.9.0;
    3
    4
    pragma experimental ABIEncoderV2;
    5
    6
    import {VmSafe} from "./Vm.sol";
    7
    8
    // Helpers for parsing and writing JSON files
    9
    // To parse:
    10
    // ```
    11
    // using stdJson for string;
    12
    // string memory json = vm.readFile("<some_path>");
    13
    // json.readUint("<json_path>");
    14
    // ```
    15
    // To write:
    16
    // ```
    17
    // using stdJson for string;
    18
    // string memory json = "json";
    19
    // json.serialize("a", uint256(123));
    20
    // string memory semiFinal = json.serialize("b", string("test"));
    21
    // string memory finalJson = json.serialize("c", semiFinal);
    22
    // finalJson.write("<some_path>");
    23
    // ```
    24
    25
    library stdJson {
    26
        VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code")))));
    27
    28
        function keyExists(string memory json, string memory key) internal view returns (bool) {
    29
            return vm.keyExistsJson(json, key);
    30
        }
    31
    32
        function parseRaw(string memory json, string memory key) internal pure returns (bytes memory) {
    33
            return vm.parseJson(json, key);
    34
        }
    35
    36
        function readUint(string memory json, string memory key) internal pure returns (uint256) {
    37
            return vm.parseJsonUint(json, key);
    38
        }
    39
    40
        function readUintArray(string memory json, string memory key) internal pure returns (uint256[] memory) {
    41
            return vm.parseJsonUintArray(json, key);
    42
        }
    43
    44
        function readInt(string memory json, string memory key) internal pure returns (int256) {
    45
            return vm.parseJsonInt(json, key);
    46
        }
    47
    48
        function readIntArray(string memory json, string memory key) internal pure returns (int256[] memory) {
    49
            return vm.parseJsonIntArray(json, key);
    50
        }
    51
    52
        function readBytes32(string memory json, string memory key) internal pure returns (bytes32) {
    53
            return vm.parseJsonBytes32(json, key);
    54
        }
    55
    56
        function readBytes32Array(string memory json, string memory key) internal pure returns (bytes32[] memory) {
    57
            return vm.parseJsonBytes32Array(json, key);
    58
        }
    59
    60
        function readString(string memory json, string memory key) internal pure returns (string memory) {
    61
            return vm.parseJsonString(json, key);
    62
        }
    63
    64
        function readStringArray(string memory json, string memory key) internal pure returns (string[] memory) {
    65
            return vm.parseJsonStringArray(json, key);
    66
        }
    67
    68
        function readAddress(string memory json, string memory key) internal pure returns (address) {
    69
            return vm.parseJsonAddress(json, key);
    70
        }
    71
    72
        function readAddressArray(string memory json, string memory key) internal pure returns (address[] memory) {
    73
            return vm.parseJsonAddressArray(json, key);
    74
        }
    75
    76
        function readBool(string memory json, string memory key) internal pure returns (bool) {
    77
            return vm.parseJsonBool(json, key);
    78
        }
    79
    80
        function readBoolArray(string memory json, string memory key) internal pure returns (bool[] memory) {
    81
            return vm.parseJsonBoolArray(json, key);
    82
        }
    83
    84
        function readBytes(string memory json, string memory key) internal pure returns (bytes memory) {
    85
            return vm.parseJsonBytes(json, key);
    86
        }
    87
    88
        function readBytesArray(string memory json, string memory key) internal pure returns (bytes[] memory) {
    89
            return vm.parseJsonBytesArray(json, key);
    90
        }
    91
    92
        function readUintOr(string memory json, string memory key, uint256 defaultValue) internal view returns (uint256) {
    93
            return keyExists(json, key) ? readUint(json, key) : defaultValue;
    94
        }
    95
    96
        function readUintArrayOr(string memory json, string memory key, uint256[] memory defaultValue)
    97
            internal
    98
            view
    99
            returns (uint256[] memory)
    100
        {
    101
            return keyExists(json, key) ? readUintArray(json, key) : defaultValue;
    102
        }
    103
    104
        function readIntOr(string memory json, string memory key, int256 defaultValue) internal view returns (int256) {
    105
            return keyExists(json, key) ? readInt(json, key) : defaultValue;
    106
        }
    107
    108
        function readIntArrayOr(string memory json, string memory key, int256[] memory defaultValue)
    109
            internal
    110
            view
    111
            returns (int256[] memory)
    112
        {
    113
            return keyExists(json, key) ? readIntArray(json, key) : defaultValue;
    114
        }
    115
    116
        function readBytes32Or(string memory json, string memory key, bytes32 defaultValue)
    117
            internal
    118
            view
    119
            returns (bytes32)
    120
        {
    121
            return keyExists(json, key) ? readBytes32(json, key) : defaultValue;
    122
        }
    123
    124
        function readBytes32ArrayOr(string memory json, string memory key, bytes32[] memory defaultValue)
    125
            internal
    126
            view
    127
            returns (bytes32[] memory)
    128
        {
    129
            return keyExists(json, key) ? readBytes32Array(json, key) : defaultValue;
    130
        }
    131
    132
        function readStringOr(string memory json, string memory key, string memory defaultValue)
    133
            internal
    134
            view
    135
            returns (string memory)
    136
        {
    137
            return keyExists(json, key) ? readString(json, key) : defaultValue;
    138
        }
    139
    140
        function readStringArrayOr(string memory json, string memory key, string[] memory defaultValue)
    141
            internal
    142
            view
    143
            returns (string[] memory)
    144
        {
    145
            return keyExists(json, key) ? readStringArray(json, key) : defaultValue;
    146
        }
    147
    148
        function readAddressOr(string memory json, string memory key, address defaultValue)
    149
            internal
    150
            view
    151
            returns (address)
    152
        {
    153
            return keyExists(json, key) ? readAddress(json, key) : defaultValue;
    154
        }
    155
    156
        function readAddressArrayOr(string memory json, string memory key, address[] memory defaultValue)
    157
            internal
    158
            view
    159
            returns (address[] memory)
    160
        {
    161
            return keyExists(json, key) ? readAddressArray(json, key) : defaultValue;
    162
        }
    163
    164
        function readBoolOr(string memory json, string memory key, bool defaultValue) internal view returns (bool) {
    165
            return keyExists(json, key) ? readBool(json, key) : defaultValue;
    166
        }
    167
    168
        function readBoolArrayOr(string memory json, string memory key, bool[] memory defaultValue)
    169
            internal
    170
            view
    171
            returns (bool[] memory)
    172
        {
    173
            return keyExists(json, key) ? readBoolArray(json, key) : defaultValue;
    174
        }
    175
    176
        function readBytesOr(string memory json, string memory key, bytes memory defaultValue)
    177
            internal
    178
            view
    179
            returns (bytes memory)
    180
        {
    181
            return keyExists(json, key) ? readBytes(json, key) : defaultValue;
    182
        }
    183
    184
        function readBytesArrayOr(string memory json, string memory key, bytes[] memory defaultValue)
    185
            internal
    186
            view
    187
            returns (bytes[] memory)
    188
        {
    189
            return keyExists(json, key) ? readBytesArray(json, key) : defaultValue;
    190
        }
    191
    192
        function serialize(string memory jsonKey, string memory rootObject) internal returns (string memory) {
    193
            return vm.serializeJson(jsonKey, rootObject);
    194
        }
    195
    196
        function serialize(string memory jsonKey, string memory key, bool value) internal returns (string memory) {
    197
            return vm.serializeBool(jsonKey, key, value);
    198
        }
    199
    200
        function serialize(string memory jsonKey, string memory key, bool[] memory value)
    201
            internal
    202
            returns (string memory)
    203
        {
    204
            return vm.serializeBool(jsonKey, key, value);
    205
        }
    206
    207
        function serialize(string memory jsonKey, string memory key, uint256 value) internal returns (string memory) {
    208
            return vm.serializeUint(jsonKey, key, value);
    209
        }
    210
    211
        function serialize(string memory jsonKey, string memory key, uint256[] memory value)
    212
            internal
    213
            returns (string memory)
    214
        {
    215
            return vm.serializeUint(jsonKey, key, value);
    216
        }
    217
    218
        function serialize(string memory jsonKey, string memory key, int256 value) internal returns (string memory) {
    219
            return vm.serializeInt(jsonKey, key, value);
    220
        }
    221
    222
        function serialize(string memory jsonKey, string memory key, int256[] memory value)
    223
            internal
    224
            returns (string memory)
    225
        {
    226
            return vm.serializeInt(jsonKey, key, value);
    227
        }
    228
    229
        function serialize(string memory jsonKey, string memory key, address value) internal returns (string memory) {
    230
            return vm.serializeAddress(jsonKey, key, value);
    231
        }
    232
    233
        function serialize(string memory jsonKey, string memory key, address[] memory value)
    234
            internal
    235
            returns (string memory)
    236
        {
    237
            return vm.serializeAddress(jsonKey, key, value);
    238
        }
    239
    240
        function serialize(string memory jsonKey, string memory key, bytes32 value) internal returns (string memory) {
    241
            return vm.serializeBytes32(jsonKey, key, value);
    242
        }
    243
    244
        function serialize(string memory jsonKey, string memory key, bytes32[] memory value)
    245
            internal
    246
            returns (string memory)
    247
        {
    248
            return vm.serializeBytes32(jsonKey, key, value);
    249
        }
    250
    251
        function serialize(string memory jsonKey, string memory key, bytes memory value) internal returns (string memory) {
    252
            return vm.serializeBytes(jsonKey, key, value);
    253
        }
    254
    255
        function serialize(string memory jsonKey, string memory key, bytes[] memory value)
    256
            internal
    257
            returns (string memory)
    258
        {
    259
            return vm.serializeBytes(jsonKey, key, value);
    260
        }
    261
    262
        function serialize(string memory jsonKey, string memory key, string memory value)
    263
            internal
    264
            returns (string memory)
    265
        {
    266
            return vm.serializeString(jsonKey, key, value);
    267
        }
    268
    269
        function serialize(string memory jsonKey, string memory key, string[] memory value)
    270
            internal
    271
            returns (string memory)
    272
        {
    273
            return vm.serializeString(jsonKey, key, value);
    274
        }
    275
    276
        function write(string memory jsonKey, string memory path) internal {
    277
            vm.writeJson(jsonKey, path);
    278
        }
    279
    280
        function write(string memory jsonKey, string memory path, string memory valueKey) internal {
    281
            vm.writeJson(jsonKey, path, valueKey);
    282
        }
    283
    }
    284
    100.0% lib/forge-std/src/StdMath.sol
    Lines covered: 1 / 1 (100.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    pragma solidity >=0.6.2 <0.9.0;
    3
    4
    library stdMath {
    5
        int256 private constant INT256_MIN = -57896044618658097711785492504343953926634992332820282019728792003956564819968;
    6
    7
        function abs(int256 a) internal pure returns (uint256) {
    8
            // Required or it will fail when `a = type(int256).min`
    9
            if (a == INT256_MIN) {
    10
                return 57896044618658097711785492504343953926634992332820282019728792003956564819968;
    11
            }
    12
    13
            return uint256(a > 0 ? a : -a);
    14
        }
    15
    16
        function delta(uint256 a, uint256 b) internal pure returns (uint256) {
    17
            return a > b ? a - b : b - a;
    18
        }
    19
    20
        function delta(int256 a, int256 b) internal pure returns (uint256) {
    21
            // a and b are of the same sign
    22
            // this works thanks to two's complement, the left-most bit is the sign bit
    23
            if ((a ^ b) > -1) {
    24
                return delta(abs(a), abs(b));
    25
            }
    26
    27
            // a and b are of opposite signs
    28
            return abs(a) + abs(b);
    29
        }
    30
    31
        function percentDelta(uint256 a, uint256 b) internal pure returns (uint256) {
    32
            uint256 absDelta = delta(a, b);
    33
    34
            return absDelta * 1e18 / b;
    35
        }
    36
    37
        function percentDelta(int256 a, int256 b) internal pure returns (uint256) {
    38
            uint256 absDelta = delta(a, b);
    39
            uint256 absB = abs(b);
    40
    41
            return absDelta * 1e18 / absB;
    42
        }
    43
    }
    44
    100.0% lib/forge-std/src/StdStorage.sol
    Lines covered: 2 / 2 (100.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    pragma solidity >=0.6.2 <0.9.0;
    3
    4
    import {Vm} from "./Vm.sol";
    5
    6
    struct FindData {
    7
        uint256 slot;
    8
        uint256 offsetLeft;
    9
        uint256 offsetRight;
    10
        bool found;
    11
    }
    12
    13
    struct StdStorage {
    14
        mapping(address => mapping(bytes4 => mapping(bytes32 => FindData))) finds;
    15
        bytes32[] _keys;
    16
        bytes4 _sig;
    17
        uint256 _depth;
    18
        address _target;
    19
        bytes32 _set;
    20
        bool _enable_packed_slots;
    21
        bytes _calldata;
    22
    }
    23
    24
    library stdStorageSafe {
    25
        event SlotFound(address who, bytes4 fsig, bytes32 keysHash, uint256 slot);
    26
        event WARNING_UninitedSlot(address who, uint256 slot);
    27
    28
        Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code")))));
    29
        uint256 constant UINT256_MAX = 115792089237316195423570985008687907853269984665640564039457584007913129639935;
    30
    31
        function sigs(string memory sigStr) internal pure returns (bytes4) {
    32
            return bytes4(keccak256(bytes(sigStr)));
    33
        }
    34
    35
        function getCallParams(StdStorage storage self) internal view returns (bytes memory) {
    36
            if (self._calldata.length == 0) {
    37
                return flatten(self._keys);
    38
            } else {
    39
                return self._calldata;
    40
            }
    41
        }
    42
    43
        // Calls target contract with configured parameters
    44
        function callTarget(StdStorage storage self) internal view returns (bool, bytes32) {
    45
            bytes memory cald = abi.encodePacked(self._sig, getCallParams(self));
    46
            (bool success, bytes memory rdat) = self._target.staticcall(cald);
    47
            bytes32 result = bytesToBytes32(rdat, 32 * self._depth);
    48
    49
            return (success, result);
    50
        }
    51
    52
        // Tries mutating slot value to determine if the targeted value is stored in it.
    53
        // If current value is 0, then we are setting slot value to type(uint256).max
    54
        // Otherwise, we set it to 0. That way, return value should always be affected.
    55
        function checkSlotMutatesCall(StdStorage storage self, bytes32 slot) internal returns (bool) {
    56
            bytes32 prevSlotValue = vm.load(self._target, slot);
    57
            (bool success, bytes32 prevReturnValue) = callTarget(self);
    58
    59
            bytes32 testVal = prevReturnValue == bytes32(0) ? bytes32(UINT256_MAX) : bytes32(0);
    60
            vm.store(self._target, slot, testVal);
    61
    62
            (, bytes32 newReturnValue) = callTarget(self);
    63
    64
            vm.store(self._target, slot, prevSlotValue);
    65
    66
            return (success && (prevReturnValue != newReturnValue));
    67
        }
    68
    69
        // Tries setting one of the bits in slot to 1 until return value changes.
    70
        // Index of resulted bit is an offset packed slot has from left/right side
    71
        function findOffset(StdStorage storage self, bytes32 slot, bool left) internal returns (bool, uint256) {
    72
            for (uint256 offset = 0; offset < 256; offset++) {
    73
                uint256 valueToPut = left ? (1 << (255 - offset)) : (1 << offset);
    74
                vm.store(self._target, slot, bytes32(valueToPut));
    75
    76
                (bool success, bytes32 data) = callTarget(self);
    77
    78
                if (success && (uint256(data) > 0)) {
    79
                    return (true, offset);
    80
                }
    81
            }
    82
            return (false, 0);
    83
        }
    84
    85
        function findOffsets(StdStorage storage self, bytes32 slot) internal returns (bool, uint256, uint256) {
    86
            bytes32 prevSlotValue = vm.load(self._target, slot);
    87
    88
            (bool foundLeft, uint256 offsetLeft) = findOffset(self, slot, true);
    89
            (bool foundRight, uint256 offsetRight) = findOffset(self, slot, false);
    90
    91
            // `findOffset` may mutate slot value, so we are setting it to initial value
    92
            vm.store(self._target, slot, prevSlotValue);
    93
            return (foundLeft && foundRight, offsetLeft, offsetRight);
    94
        }
    95
    96
        function find(StdStorage storage self) internal returns (FindData storage) {
    97
            return find(self, true);
    98
        }
    99
    100
        /// @notice find an arbitrary storage slot given a function sig, input data, address of the contract and a value to check against
    101
        // slot complexity:
    102
        //  if flat, will be bytes32(uint256(uint));
    103
        //  if map, will be keccak256(abi.encode(key, uint(slot)));
    104
        //  if deep map, will be keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))));
    105
        //  if map struct, will be bytes32(uint256(keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))))) + structFieldDepth);
    106
        function find(StdStorage storage self, bool _clear) internal returns (FindData storage) {
    107
            address who = self._target;
    108
            bytes4 fsig = self._sig;
    109
            uint256 field_depth = self._depth;
    110
            bytes memory params = getCallParams(self);
    111
    112
            // calldata to test against
    113
            if (self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))].found) {
    114
                if (_clear) {
    115
                    clear(self);
    116
                }
    117
                return self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))];
    118
            }
    119
            vm.record();
    120
            (, bytes32 callResult) = callTarget(self);
    121
            (bytes32[] memory reads,) = vm.accesses(address(who));
    122
    123
            if (reads.length == 0) {
    124
                revert("stdStorage find(StdStorage): No storage use detected for target.");
    125
            } else {
    126
                for (uint256 i = reads.length; --i >= 0;) {
    127
                    bytes32 prev = vm.load(who, reads[i]);
    128
                    if (prev == bytes32(0)) {
    129
                        emit WARNING_UninitedSlot(who, uint256(reads[i]));
    130
                    }
    131
    132
                    if (!checkSlotMutatesCall(self, reads[i])) {
    133
                        continue;
    134
                    }
    135
    136
                    (uint256 offsetLeft, uint256 offsetRight) = (0, 0);
    137
    138
                    if (self._enable_packed_slots) {
    139
                        bool found;
    140
                        (found, offsetLeft, offsetRight) = findOffsets(self, reads[i]);
    141
                        if (!found) {
    142
                            continue;
    143
                        }
    144
                    }
    145
    146
                    // Check that value between found offsets is equal to the current call result
    147
                    uint256 curVal = (uint256(prev) & getMaskByOffsets(offsetLeft, offsetRight)) >> offsetRight;
    148
    149
                    if (uint256(callResult) != curVal) {
    150
                        continue;
    151
                    }
    152
    153
                    emit SlotFound(who, fsig, keccak256(abi.encodePacked(params, field_depth)), uint256(reads[i]));
    154
                    self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))] =
    155
                        FindData(uint256(reads[i]), offsetLeft, offsetRight, true);
    156
                    break;
    157
                }
    158
            }
    159
    160
            require(
    161
                self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))].found,
    162
                "stdStorage find(StdStorage): Slot(s) not found."
    163
            );
    164
    165
            if (_clear) {
    166
                clear(self);
    167
            }
    168
            return self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))];
    169
        }
    170
    171
        function target(StdStorage storage self, address _target) internal returns (StdStorage storage) {
    172
            self._target = _target;
    173
            return self;
    174
        }
    175
    176
        function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) {
    177
            self._sig = _sig;
    178
            return self;
    179
        }
    180
    181
        function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) {
    182
            self._sig = sigs(_sig);
    183
            return self;
    184
        }
    185
    186
        function with_calldata(StdStorage storage self, bytes memory _calldata) internal returns (StdStorage storage) {
    187
            self._calldata = _calldata;
    188
            return self;
    189
        }
    190
    191
        function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) {
    192
            self._keys.push(bytes32(uint256(uint160(who))));
    193
            return self;
    194
        }
    195
    196
        function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) {
    197
            self._keys.push(bytes32(amt));
    198
            return self;
    199
        }
    200
    201
        function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) {
    202
            self._keys.push(key);
    203
            return self;
    204
        }
    205
    206
        function enable_packed_slots(StdStorage storage self) internal returns (StdStorage storage) {
    207
            self._enable_packed_slots = true;
    208
            return self;
    209
        }
    210
    211
        function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) {
    212
            self._depth = _depth;
    213
            return self;
    214
        }
    215
    216
        function read(StdStorage storage self) private returns (bytes memory) {
    217
            FindData storage data = find(self, false);
    218
            uint256 mask = getMaskByOffsets(data.offsetLeft, data.offsetRight);
    219
            uint256 value = (uint256(vm.load(self._target, bytes32(data.slot))) & mask) >> data.offsetRight;
    220
            clear(self);
    221
            return abi.encode(value);
    222
        }
    223
    224
        function read_bytes32(StdStorage storage self) internal returns (bytes32) {
    225
            return abi.decode(read(self), (bytes32));
    226
        }
    227
    228
        function read_bool(StdStorage storage self) internal returns (bool) {
    229
            int256 v = read_int(self);
    230
            if (v == 0) return false;
    231
            if (v == 1) return true;
    232
            revert("stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool.");
    233
        }
    234
    235
        function read_address(StdStorage storage self) internal returns (address) {
    236
            return abi.decode(read(self), (address));
    237
        }
    238
    239
        function read_uint(StdStorage storage self) internal returns (uint256) {
    240
            return abi.decode(read(self), (uint256));
    241
        }
    242
    243
        function read_int(StdStorage storage self) internal returns (int256) {
    244
            return abi.decode(read(self), (int256));
    245
        }
    246
    247
        function parent(StdStorage storage self) internal returns (uint256, bytes32) {
    248
            address who = self._target;
    249
            uint256 field_depth = self._depth;
    250
            vm.startMappingRecording();
    251
            uint256 child = find(self, true).slot - field_depth;
    252
            (bool found, bytes32 key, bytes32 parent_slot) = vm.getMappingKeyAndParentOf(who, bytes32(child));
    253
            if (!found) {
    254
                revert(
    255
                    "stdStorage read_bool(StdStorage): Cannot find parent. Make sure you give a slot and startMappingRecording() has been called."
    256
                );
    257
            }
    258
            return (uint256(parent_slot), key);
    259
        }
    260
    261
        function root(StdStorage storage self) internal returns (uint256) {
    262
            address who = self._target;
    263
            uint256 field_depth = self._depth;
    264
            vm.startMappingRecording();
    265
            uint256 child = find(self, true).slot - field_depth;
    266
            bool found;
    267
            bytes32 root_slot;
    268
            bytes32 parent_slot;
    269
            (found,, parent_slot) = vm.getMappingKeyAndParentOf(who, bytes32(child));
    270
            if (!found) {
    271
                revert(
    272
                    "stdStorage read_bool(StdStorage): Cannot find parent. Make sure you give a slot and startMappingRecording() has been called."
    273
                );
    274
            }
    275
            while (found) {
    276
                root_slot = parent_slot;
    277
                (found,, parent_slot) = vm.getMappingKeyAndParentOf(who, bytes32(root_slot));
    278
            }
    279
            return uint256(root_slot);
    280
        }
    281
    282
        function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) {
    283
            bytes32 out;
    284
    285
            uint256 max = b.length > 32 ? 32 : b.length;
    286
            for (uint256 i = 0; i < max; i++) {
    287
                out |= bytes32(b[offset + i] & 0xFF) >> (i * 8);
    288
            }
    289
            return out;
    290
        }
    291
    292
        function flatten(bytes32[] memory b) private pure returns (bytes memory) {
    293
            bytes memory result = new bytes(b.length * 32);
    294
            for (uint256 i = 0; i < b.length; i++) {
    295
                bytes32 k = b[i];
    296
                /// @solidity memory-safe-assembly
    297
                assembly {
    298
                    mstore(add(result, add(32, mul(32, i))), k)
    299
                }
    300
            }
    301
    302
            return result;
    303
        }
    304
    305
        function clear(StdStorage storage self) internal {
    306
            delete self._target;
    307
            delete self._sig;
    308
            delete self._keys;
    309
            delete self._depth;
    310
            delete self._enable_packed_slots;
    311
            delete self._calldata;
    312
        }
    313
    314
        // Returns mask which contains non-zero bits for values between `offsetLeft` and `offsetRight`
    315
        // (slotValue & mask) >> offsetRight will be the value of the given packed variable
    316
        function getMaskByOffsets(uint256 offsetLeft, uint256 offsetRight) internal pure returns (uint256 mask) {
    317
            // mask = ((1 << (256 - (offsetRight + offsetLeft))) - 1) << offsetRight;
    318
            // using assembly because (1 << 256) causes overflow
    319
            assembly {
    320
                mask := shl(offsetRight, sub(shl(sub(256, add(offsetRight, offsetLeft)), 1), 1))
    321
            }
    322
        }
    323
    324
        // Returns slot value with updated packed variable.
    325
        function getUpdatedSlotValue(bytes32 curValue, uint256 varValue, uint256 offsetLeft, uint256 offsetRight)
    326
            internal
    327
            pure
    328
            returns (bytes32 newValue)
    329
        {
    330
            return bytes32((uint256(curValue) & ~getMaskByOffsets(offsetLeft, offsetRight)) | (varValue << offsetRight));
    331
        }
    332
    }
    333
    334
    library stdStorage {
    335
        Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code")))));
    336
    337
        function sigs(string memory sigStr) internal pure returns (bytes4) {
    338
            return stdStorageSafe.sigs(sigStr);
    339
        }
    340
    341
        function find(StdStorage storage self) internal returns (uint256) {
    342
            return find(self, true);
    343
        }
    344
    345
        function find(StdStorage storage self, bool _clear) internal returns (uint256) {
    346
            return stdStorageSafe.find(self, _clear).slot;
    347
        }
    348
    349
        function target(StdStorage storage self, address _target) internal returns (StdStorage storage) {
    350
            return stdStorageSafe.target(self, _target);
    351
        }
    352
    353
        function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) {
    354
            return stdStorageSafe.sig(self, _sig);
    355
        }
    356
    357
        function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) {
    358
            return stdStorageSafe.sig(self, _sig);
    359
        }
    360
    361
        function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) {
    362
            return stdStorageSafe.with_key(self, who);
    363
        }
    364
    365
        function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) {
    366
            return stdStorageSafe.with_key(self, amt);
    367
        }
    368
    369
        function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) {
    370
            return stdStorageSafe.with_key(self, key);
    371
        }
    372
    373
        function with_calldata(StdStorage storage self, bytes memory _calldata) internal returns (StdStorage storage) {
    374
            return stdStorageSafe.with_calldata(self, _calldata);
    375
        }
    376
    377
        function enable_packed_slots(StdStorage storage self) internal returns (StdStorage storage) {
    378
            return stdStorageSafe.enable_packed_slots(self);
    379
        }
    380
    381
        function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) {
    382
            return stdStorageSafe.depth(self, _depth);
    383
        }
    384
    385
        function clear(StdStorage storage self) internal {
    386
            stdStorageSafe.clear(self);
    387
        }
    388
    389
        function checked_write(StdStorage storage self, address who) internal {
    390
            checked_write(self, bytes32(uint256(uint160(who))));
    391
        }
    392
    393
        function checked_write(StdStorage storage self, uint256 amt) internal {
    394
            checked_write(self, bytes32(amt));
    395
        }
    396
    397
        function checked_write_int(StdStorage storage self, int256 val) internal {
    398
            checked_write(self, bytes32(uint256(val)));
    399
        }
    400
    401
        function checked_write(StdStorage storage self, bool write) internal {
    402
            bytes32 t;
    403
            /// @solidity memory-safe-assembly
    404
            assembly {
    405
                t := write
    406
            }
    407
            checked_write(self, t);
    408
        }
    409
    410
        function checked_write(StdStorage storage self, bytes32 set) internal {
    411
            address who = self._target;
    412
            bytes4 fsig = self._sig;
    413
            uint256 field_depth = self._depth;
    414
            bytes memory params = stdStorageSafe.getCallParams(self);
    415
    416
            if (!self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))].found) {
    417
                find(self, false);
    418
            }
    419
            FindData storage data = self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))];
    420
            if ((data.offsetLeft + data.offsetRight) > 0) {
    421
                uint256 maxVal = 2 ** (256 - (data.offsetLeft + data.offsetRight));
    422
                require(
    423
                    uint256(set) < maxVal,
    424
                    string(
    425
                        abi.encodePacked(
    426
                            "stdStorage find(StdStorage): Packed slot. We can't fit value greater than ",
    427
                            vm.toString(maxVal)
    428
                        )
    429
                    )
    430
                );
    431
            }
    432
            bytes32 curVal = vm.load(who, bytes32(data.slot));
    433
            bytes32 valToSet = stdStorageSafe.getUpdatedSlotValue(curVal, uint256(set), data.offsetLeft, data.offsetRight);
    434
    435
            vm.store(who, bytes32(data.slot), valToSet);
    436
    437
            (bool success, bytes32 callResult) = stdStorageSafe.callTarget(self);
    438
    439
            if (!success || callResult != set) {
    440
                vm.store(who, bytes32(data.slot), curVal);
    441
                revert("stdStorage find(StdStorage): Failed to write value.");
    442
            }
    443
            clear(self);
    444
        }
    445
    446
        function read_bytes32(StdStorage storage self) internal returns (bytes32) {
    447
            return stdStorageSafe.read_bytes32(self);
    448
        }
    449
    450
        function read_bool(StdStorage storage self) internal returns (bool) {
    451
            return stdStorageSafe.read_bool(self);
    452
        }
    453
    454
        function read_address(StdStorage storage self) internal returns (address) {
    455
            return stdStorageSafe.read_address(self);
    456
        }
    457
    458
        function read_uint(StdStorage storage self) internal returns (uint256) {
    459
            return stdStorageSafe.read_uint(self);
    460
        }
    461
    462
        function read_int(StdStorage storage self) internal returns (int256) {
    463
            return stdStorageSafe.read_int(self);
    464
        }
    465
    466
        function parent(StdStorage storage self) internal returns (uint256, bytes32) {
    467
            return stdStorageSafe.parent(self);
    468
        }
    469
    470
        function root(StdStorage storage self) internal returns (uint256) {
    471
            return stdStorageSafe.root(self);
    472
        }
    473
    }
    474
    100.0% lib/forge-std/src/StdStyle.sol
    Lines covered: 1 / 1 (100.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    pragma solidity >=0.4.22 <0.9.0;
    3
    4
    import {VmSafe} from "./Vm.sol";
    5
    6
    library StdStyle {
    7
        VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code")))));
    8
    9
        string constant RED = "\u001b[91m";
    10
        string constant GREEN = "\u001b[92m";
    11
        string constant YELLOW = "\u001b[93m";
    12
        string constant BLUE = "\u001b[94m";
    13
        string constant MAGENTA = "\u001b[95m";
    14
        string constant CYAN = "\u001b[96m";
    15
        string constant BOLD = "\u001b[1m";
    16
        string constant DIM = "\u001b[2m";
    17
        string constant ITALIC = "\u001b[3m";
    18
        string constant UNDERLINE = "\u001b[4m";
    19
        string constant INVERSE = "\u001b[7m";
    20
        string constant RESET = "\u001b[0m";
    21
    22
        function styleConcat(string memory style, string memory self) private pure returns (string memory) {
    23
            return string(abi.encodePacked(style, self, RESET));
    24
        }
    25
    26
        function red(string memory self) internal pure returns (string memory) {
    27
            return styleConcat(RED, self);
    28
        }
    29
    30
        function red(uint256 self) internal pure returns (string memory) {
    31
            return red(vm.toString(self));
    32
        }
    33
    34
        function red(int256 self) internal pure returns (string memory) {
    35
            return red(vm.toString(self));
    36
        }
    37
    38
        function red(address self) internal pure returns (string memory) {
    39
            return red(vm.toString(self));
    40
        }
    41
    42
        function red(bool self) internal pure returns (string memory) {
    43
            return red(vm.toString(self));
    44
        }
    45
    46
        function redBytes(bytes memory self) internal pure returns (string memory) {
    47
            return red(vm.toString(self));
    48
        }
    49
    50
        function redBytes32(bytes32 self) internal pure returns (string memory) {
    51
            return red(vm.toString(self));
    52
        }
    53
    54
        function green(string memory self) internal pure returns (string memory) {
    55
            return styleConcat(GREEN, self);
    56
        }
    57
    58
        function green(uint256 self) internal pure returns (string memory) {
    59
            return green(vm.toString(self));
    60
        }
    61
    62
        function green(int256 self) internal pure returns (string memory) {
    63
            return green(vm.toString(self));
    64
        }
    65
    66
        function green(address self) internal pure returns (string memory) {
    67
            return green(vm.toString(self));
    68
        }
    69
    70
        function green(bool self) internal pure returns (string memory) {
    71
            return green(vm.toString(self));
    72
        }
    73
    74
        function greenBytes(bytes memory self) internal pure returns (string memory) {
    75
            return green(vm.toString(self));
    76
        }
    77
    78
        function greenBytes32(bytes32 self) internal pure returns (string memory) {
    79
            return green(vm.toString(self));
    80
        }
    81
    82
        function yellow(string memory self) internal pure returns (string memory) {
    83
            return styleConcat(YELLOW, self);
    84
        }
    85
    86
        function yellow(uint256 self) internal pure returns (string memory) {
    87
            return yellow(vm.toString(self));
    88
        }
    89
    90
        function yellow(int256 self) internal pure returns (string memory) {
    91
            return yellow(vm.toString(self));
    92
        }
    93
    94
        function yellow(address self) internal pure returns (string memory) {
    95
            return yellow(vm.toString(self));
    96
        }
    97
    98
        function yellow(bool self) internal pure returns (string memory) {
    99
            return yellow(vm.toString(self));
    100
        }
    101
    102
        function yellowBytes(bytes memory self) internal pure returns (string memory) {
    103
            return yellow(vm.toString(self));
    104
        }
    105
    106
        function yellowBytes32(bytes32 self) internal pure returns (string memory) {
    107
            return yellow(vm.toString(self));
    108
        }
    109
    110
        function blue(string memory self) internal pure returns (string memory) {
    111
            return styleConcat(BLUE, self);
    112
        }
    113
    114
        function blue(uint256 self) internal pure returns (string memory) {
    115
            return blue(vm.toString(self));
    116
        }
    117
    118
        function blue(int256 self) internal pure returns (string memory) {
    119
            return blue(vm.toString(self));
    120
        }
    121
    122
        function blue(address self) internal pure returns (string memory) {
    123
            return blue(vm.toString(self));
    124
        }
    125
    126
        function blue(bool self) internal pure returns (string memory) {
    127
            return blue(vm.toString(self));
    128
        }
    129
    130
        function blueBytes(bytes memory self) internal pure returns (string memory) {
    131
            return blue(vm.toString(self));
    132
        }
    133
    134
        function blueBytes32(bytes32 self) internal pure returns (string memory) {
    135
            return blue(vm.toString(self));
    136
        }
    137
    138
        function magenta(string memory self) internal pure returns (string memory) {
    139
            return styleConcat(MAGENTA, self);
    140
        }
    141
    142
        function magenta(uint256 self) internal pure returns (string memory) {
    143
            return magenta(vm.toString(self));
    144
        }
    145
    146
        function magenta(int256 self) internal pure returns (string memory) {
    147
            return magenta(vm.toString(self));
    148
        }
    149
    150
        function magenta(address self) internal pure returns (string memory) {
    151
            return magenta(vm.toString(self));
    152
        }
    153
    154
        function magenta(bool self) internal pure returns (string memory) {
    155
            return magenta(vm.toString(self));
    156
        }
    157
    158
        function magentaBytes(bytes memory self) internal pure returns (string memory) {
    159
            return magenta(vm.toString(self));
    160
        }
    161
    162
        function magentaBytes32(bytes32 self) internal pure returns (string memory) {
    163
            return magenta(vm.toString(self));
    164
        }
    165
    166
        function cyan(string memory self) internal pure returns (string memory) {
    167
            return styleConcat(CYAN, self);
    168
        }
    169
    170
        function cyan(uint256 self) internal pure returns (string memory) {
    171
            return cyan(vm.toString(self));
    172
        }
    173
    174
        function cyan(int256 self) internal pure returns (string memory) {
    175
            return cyan(vm.toString(self));
    176
        }
    177
    178
        function cyan(address self) internal pure returns (string memory) {
    179
            return cyan(vm.toString(self));
    180
        }
    181
    182
        function cyan(bool self) internal pure returns (string memory) {
    183
            return cyan(vm.toString(self));
    184
        }
    185
    186
        function cyanBytes(bytes memory self) internal pure returns (string memory) {
    187
            return cyan(vm.toString(self));
    188
        }
    189
    190
        function cyanBytes32(bytes32 self) internal pure returns (string memory) {
    191
            return cyan(vm.toString(self));
    192
        }
    193
    194
        function bold(string memory self) internal pure returns (string memory) {
    195
            return styleConcat(BOLD, self);
    196
        }
    197
    198
        function bold(uint256 self) internal pure returns (string memory) {
    199
            return bold(vm.toString(self));
    200
        }
    201
    202
        function bold(int256 self) internal pure returns (string memory) {
    203
            return bold(vm.toString(self));
    204
        }
    205
    206
        function bold(address self) internal pure returns (string memory) {
    207
            return bold(vm.toString(self));
    208
        }
    209
    210
        function bold(bool self) internal pure returns (string memory) {
    211
            return bold(vm.toString(self));
    212
        }
    213
    214
        function boldBytes(bytes memory self) internal pure returns (string memory) {
    215
            return bold(vm.toString(self));
    216
        }
    217
    218
        function boldBytes32(bytes32 self) internal pure returns (string memory) {
    219
            return bold(vm.toString(self));
    220
        }
    221
    222
        function dim(string memory self) internal pure returns (string memory) {
    223
            return styleConcat(DIM, self);
    224
        }
    225
    226
        function dim(uint256 self) internal pure returns (string memory) {
    227
            return dim(vm.toString(self));
    228
        }
    229
    230
        function dim(int256 self) internal pure returns (string memory) {
    231
            return dim(vm.toString(self));
    232
        }
    233
    234
        function dim(address self) internal pure returns (string memory) {
    235
            return dim(vm.toString(self));
    236
        }
    237
    238
        function dim(bool self) internal pure returns (string memory) {
    239
            return dim(vm.toString(self));
    240
        }
    241
    242
        function dimBytes(bytes memory self) internal pure returns (string memory) {
    243
            return dim(vm.toString(self));
    244
        }
    245
    246
        function dimBytes32(bytes32 self) internal pure returns (string memory) {
    247
            return dim(vm.toString(self));
    248
        }
    249
    250
        function italic(string memory self) internal pure returns (string memory) {
    251
            return styleConcat(ITALIC, self);
    252
        }
    253
    254
        function italic(uint256 self) internal pure returns (string memory) {
    255
            return italic(vm.toString(self));
    256
        }
    257
    258
        function italic(int256 self) internal pure returns (string memory) {
    259
            return italic(vm.toString(self));
    260
        }
    261
    262
        function italic(address self) internal pure returns (string memory) {
    263
            return italic(vm.toString(self));
    264
        }
    265
    266
        function italic(bool self) internal pure returns (string memory) {
    267
            return italic(vm.toString(self));
    268
        }
    269
    270
        function italicBytes(bytes memory self) internal pure returns (string memory) {
    271
            return italic(vm.toString(self));
    272
        }
    273
    274
        function italicBytes32(bytes32 self) internal pure returns (string memory) {
    275
            return italic(vm.toString(self));
    276
        }
    277
    278
        function underline(string memory self) internal pure returns (string memory) {
    279
            return styleConcat(UNDERLINE, self);
    280
        }
    281
    282
        function underline(uint256 self) internal pure returns (string memory) {
    283
            return underline(vm.toString(self));
    284
        }
    285
    286
        function underline(int256 self) internal pure returns (string memory) {
    287
            return underline(vm.toString(self));
    288
        }
    289
    290
        function underline(address self) internal pure returns (string memory) {
    291
            return underline(vm.toString(self));
    292
        }
    293
    294
        function underline(bool self) internal pure returns (string memory) {
    295
            return underline(vm.toString(self));
    296
        }
    297
    298
        function underlineBytes(bytes memory self) internal pure returns (string memory) {
    299
            return underline(vm.toString(self));
    300
        }
    301
    302
        function underlineBytes32(bytes32 self) internal pure returns (string memory) {
    303
            return underline(vm.toString(self));
    304
        }
    305
    306
        function inverse(string memory self) internal pure returns (string memory) {
    307
            return styleConcat(INVERSE, self);
    308
        }
    309
    310
        function inverse(uint256 self) internal pure returns (string memory) {
    311
            return inverse(vm.toString(self));
    312
        }
    313
    314
        function inverse(int256 self) internal pure returns (string memory) {
    315
            return inverse(vm.toString(self));
    316
        }
    317
    318
        function inverse(address self) internal pure returns (string memory) {
    319
            return inverse(vm.toString(self));
    320
        }
    321
    322
        function inverse(bool self) internal pure returns (string memory) {
    323
            return inverse(vm.toString(self));
    324
        }
    325
    326
        function inverseBytes(bytes memory self) internal pure returns (string memory) {
    327
            return inverse(vm.toString(self));
    328
        }
    329
    330
        function inverseBytes32(bytes32 self) internal pure returns (string memory) {
    331
            return inverse(vm.toString(self));
    332
        }
    333
    }
    334
    100.0% lib/forge-std/src/StdToml.sol
    Lines covered: 1 / 1 (100.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    pragma solidity >=0.6.0 <0.9.0;
    3
    4
    pragma experimental ABIEncoderV2;
    5
    6
    import {VmSafe} from "./Vm.sol";
    7
    8
    // Helpers for parsing and writing TOML files
    9
    // To parse:
    10
    // ```
    11
    // using stdToml for string;
    12
    // string memory toml = vm.readFile("<some_path>");
    13
    // toml.readUint("<json_path>");
    14
    // ```
    15
    // To write:
    16
    // ```
    17
    // using stdToml for string;
    18
    // string memory json = "json";
    19
    // json.serialize("a", uint256(123));
    20
    // string memory semiFinal = json.serialize("b", string("test"));
    21
    // string memory finalJson = json.serialize("c", semiFinal);
    22
    // finalJson.write("<some_path>");
    23
    // ```
    24
    25
    library stdToml {
    26
        VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code")))));
    27
    28
        function keyExists(string memory toml, string memory key) internal view returns (bool) {
    29
            return vm.keyExistsToml(toml, key);
    30
        }
    31
    32
        function parseRaw(string memory toml, string memory key) internal pure returns (bytes memory) {
    33
            return vm.parseToml(toml, key);
    34
        }
    35
    36
        function readUint(string memory toml, string memory key) internal pure returns (uint256) {
    37
            return vm.parseTomlUint(toml, key);
    38
        }
    39
    40
        function readUintArray(string memory toml, string memory key) internal pure returns (uint256[] memory) {
    41
            return vm.parseTomlUintArray(toml, key);
    42
        }
    43
    44
        function readInt(string memory toml, string memory key) internal pure returns (int256) {
    45
            return vm.parseTomlInt(toml, key);
    46
        }
    47
    48
        function readIntArray(string memory toml, string memory key) internal pure returns (int256[] memory) {
    49
            return vm.parseTomlIntArray(toml, key);
    50
        }
    51
    52
        function readBytes32(string memory toml, string memory key) internal pure returns (bytes32) {
    53
            return vm.parseTomlBytes32(toml, key);
    54
        }
    55
    56
        function readBytes32Array(string memory toml, string memory key) internal pure returns (bytes32[] memory) {
    57
            return vm.parseTomlBytes32Array(toml, key);
    58
        }
    59
    60
        function readString(string memory toml, string memory key) internal pure returns (string memory) {
    61
            return vm.parseTomlString(toml, key);
    62
        }
    63
    64
        function readStringArray(string memory toml, string memory key) internal pure returns (string[] memory) {
    65
            return vm.parseTomlStringArray(toml, key);
    66
        }
    67
    68
        function readAddress(string memory toml, string memory key) internal pure returns (address) {
    69
            return vm.parseTomlAddress(toml, key);
    70
        }
    71
    72
        function readAddressArray(string memory toml, string memory key) internal pure returns (address[] memory) {
    73
            return vm.parseTomlAddressArray(toml, key);
    74
        }
    75
    76
        function readBool(string memory toml, string memory key) internal pure returns (bool) {
    77
            return vm.parseTomlBool(toml, key);
    78
        }
    79
    80
        function readBoolArray(string memory toml, string memory key) internal pure returns (bool[] memory) {
    81
            return vm.parseTomlBoolArray(toml, key);
    82
        }
    83
    84
        function readBytes(string memory toml, string memory key) internal pure returns (bytes memory) {
    85
            return vm.parseTomlBytes(toml, key);
    86
        }
    87
    88
        function readBytesArray(string memory toml, string memory key) internal pure returns (bytes[] memory) {
    89
            return vm.parseTomlBytesArray(toml, key);
    90
        }
    91
    92
        function readUintOr(string memory toml, string memory key, uint256 defaultValue) internal view returns (uint256) {
    93
            return keyExists(toml, key) ? readUint(toml, key) : defaultValue;
    94
        }
    95
    96
        function readUintArrayOr(string memory toml, string memory key, uint256[] memory defaultValue)
    97
            internal
    98
            view
    99
            returns (uint256[] memory)
    100
        {
    101
            return keyExists(toml, key) ? readUintArray(toml, key) : defaultValue;
    102
        }
    103
    104
        function readIntOr(string memory toml, string memory key, int256 defaultValue) internal view returns (int256) {
    105
            return keyExists(toml, key) ? readInt(toml, key) : defaultValue;
    106
        }
    107
    108
        function readIntArrayOr(string memory toml, string memory key, int256[] memory defaultValue)
    109
            internal
    110
            view
    111
            returns (int256[] memory)
    112
        {
    113
            return keyExists(toml, key) ? readIntArray(toml, key) : defaultValue;
    114
        }
    115
    116
        function readBytes32Or(string memory toml, string memory key, bytes32 defaultValue)
    117
            internal
    118
            view
    119
            returns (bytes32)
    120
        {
    121
            return keyExists(toml, key) ? readBytes32(toml, key) : defaultValue;
    122
        }
    123
    124
        function readBytes32ArrayOr(string memory toml, string memory key, bytes32[] memory defaultValue)
    125
            internal
    126
            view
    127
            returns (bytes32[] memory)
    128
        {
    129
            return keyExists(toml, key) ? readBytes32Array(toml, key) : defaultValue;
    130
        }
    131
    132
        function readStringOr(string memory toml, string memory key, string memory defaultValue)
    133
            internal
    134
            view
    135
            returns (string memory)
    136
        {
    137
            return keyExists(toml, key) ? readString(toml, key) : defaultValue;
    138
        }
    139
    140
        function readStringArrayOr(string memory toml, string memory key, string[] memory defaultValue)
    141
            internal
    142
            view
    143
            returns (string[] memory)
    144
        {
    145
            return keyExists(toml, key) ? readStringArray(toml, key) : defaultValue;
    146
        }
    147
    148
        function readAddressOr(string memory toml, string memory key, address defaultValue)
    149
            internal
    150
            view
    151
            returns (address)
    152
        {
    153
            return keyExists(toml, key) ? readAddress(toml, key) : defaultValue;
    154
        }
    155
    156
        function readAddressArrayOr(string memory toml, string memory key, address[] memory defaultValue)
    157
            internal
    158
            view
    159
            returns (address[] memory)
    160
        {
    161
            return keyExists(toml, key) ? readAddressArray(toml, key) : defaultValue;
    162
        }
    163
    164
        function readBoolOr(string memory toml, string memory key, bool defaultValue) internal view returns (bool) {
    165
            return keyExists(toml, key) ? readBool(toml, key) : defaultValue;
    166
        }
    167
    168
        function readBoolArrayOr(string memory toml, string memory key, bool[] memory defaultValue)
    169
            internal
    170
            view
    171
            returns (bool[] memory)
    172
        {
    173
            return keyExists(toml, key) ? readBoolArray(toml, key) : defaultValue;
    174
        }
    175
    176
        function readBytesOr(string memory toml, string memory key, bytes memory defaultValue)
    177
            internal
    178
            view
    179
            returns (bytes memory)
    180
        {
    181
            return keyExists(toml, key) ? readBytes(toml, key) : defaultValue;
    182
        }
    183
    184
        function readBytesArrayOr(string memory toml, string memory key, bytes[] memory defaultValue)
    185
            internal
    186
            view
    187
            returns (bytes[] memory)
    188
        {
    189
            return keyExists(toml, key) ? readBytesArray(toml, key) : defaultValue;
    190
        }
    191
    192
        function serialize(string memory jsonKey, string memory rootObject) internal returns (string memory) {
    193
            return vm.serializeJson(jsonKey, rootObject);
    194
        }
    195
    196
        function serialize(string memory jsonKey, string memory key, bool value) internal returns (string memory) {
    197
            return vm.serializeBool(jsonKey, key, value);
    198
        }
    199
    200
        function serialize(string memory jsonKey, string memory key, bool[] memory value)
    201
            internal
    202
            returns (string memory)
    203
        {
    204
            return vm.serializeBool(jsonKey, key, value);
    205
        }
    206
    207
        function serialize(string memory jsonKey, string memory key, uint256 value) internal returns (string memory) {
    208
            return vm.serializeUint(jsonKey, key, value);
    209
        }
    210
    211
        function serialize(string memory jsonKey, string memory key, uint256[] memory value)
    212
            internal
    213
            returns (string memory)
    214
        {
    215
            return vm.serializeUint(jsonKey, key, value);
    216
        }
    217
    218
        function serialize(string memory jsonKey, string memory key, int256 value) internal returns (string memory) {
    219
            return vm.serializeInt(jsonKey, key, value);
    220
        }
    221
    222
        function serialize(string memory jsonKey, string memory key, int256[] memory value)
    223
            internal
    224
            returns (string memory)
    225
        {
    226
            return vm.serializeInt(jsonKey, key, value);
    227
        }
    228
    229
        function serialize(string memory jsonKey, string memory key, address value) internal returns (string memory) {
    230
            return vm.serializeAddress(jsonKey, key, value);
    231
        }
    232
    233
        function serialize(string memory jsonKey, string memory key, address[] memory value)
    234
            internal
    235
            returns (string memory)
    236
        {
    237
            return vm.serializeAddress(jsonKey, key, value);
    238
        }
    239
    240
        function serialize(string memory jsonKey, string memory key, bytes32 value) internal returns (string memory) {
    241
            return vm.serializeBytes32(jsonKey, key, value);
    242
        }
    243
    244
        function serialize(string memory jsonKey, string memory key, bytes32[] memory value)
    245
            internal
    246
            returns (string memory)
    247
        {
    248
            return vm.serializeBytes32(jsonKey, key, value);
    249
        }
    250
    251
        function serialize(string memory jsonKey, string memory key, bytes memory value) internal returns (string memory) {
    252
            return vm.serializeBytes(jsonKey, key, value);
    253
        }
    254
    255
        function serialize(string memory jsonKey, string memory key, bytes[] memory value)
    256
            internal
    257
            returns (string memory)
    258
        {
    259
            return vm.serializeBytes(jsonKey, key, value);
    260
        }
    261
    262
        function serialize(string memory jsonKey, string memory key, string memory value)
    263
            internal
    264
            returns (string memory)
    265
        {
    266
            return vm.serializeString(jsonKey, key, value);
    267
        }
    268
    269
        function serialize(string memory jsonKey, string memory key, string[] memory value)
    270
            internal
    271
            returns (string memory)
    272
        {
    273
            return vm.serializeString(jsonKey, key, value);
    274
        }
    275
    276
        function write(string memory jsonKey, string memory path) internal {
    277
            vm.writeToml(jsonKey, path);
    278
        }
    279
    280
        function write(string memory jsonKey, string memory path, string memory valueKey) internal {
    281
            vm.writeToml(jsonKey, path, valueKey);
    282
        }
    283
    }
    284
    0.0% lib/forge-std/src/StdUtils.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    pragma solidity >=0.6.2 <0.9.0;
    3
    4
    pragma experimental ABIEncoderV2;
    5
    6
    import {IMulticall3} from "./interfaces/IMulticall3.sol";
    7
    import {VmSafe} from "./Vm.sol";
    8
    9
    abstract contract StdUtils {
    10
        /*//////////////////////////////////////////////////////////////////////////
    11
                                         CONSTANTS
    12
        //////////////////////////////////////////////////////////////////////////*/
    13
    14
        IMulticall3 private constant multicall = IMulticall3(0xcA11bde05977b3631167028862bE2a173976CA11);
    15
        VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code")))));
    16
        address private constant CONSOLE2_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67;
    17
        uint256 private constant INT256_MIN_ABS =
    18
            57896044618658097711785492504343953926634992332820282019728792003956564819968;
    19
        uint256 private constant SECP256K1_ORDER =
    20
            115792089237316195423570985008687907852837564279074904382605163141518161494337;
    21
        uint256 private constant UINT256_MAX =
    22
            115792089237316195423570985008687907853269984665640564039457584007913129639935;
    23
    24
        // Used by default when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy.
    25
        address private constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C;
    26
    27
        /*//////////////////////////////////////////////////////////////////////////
    28
                                     INTERNAL FUNCTIONS
    29
        //////////////////////////////////////////////////////////////////////////*/
    30
    31
        function _bound(uint256 x, uint256 min, uint256 max) internal pure virtual returns (uint256 result) {
    32
            require(min <= max, "StdUtils bound(uint256,uint256,uint256): Max is less than min.");
    33
            // If x is between min and max, return x directly. This is to ensure that dictionary values
    34
            // do not get shifted if the min is nonzero. More info: https://github.com/foundry-rs/forge-std/issues/188
    35
            if (x >= min && x <= max) return x;
    36
    37
            uint256 size = max - min + 1;
    38
    39
            // If the value is 0, 1, 2, 3, wrap that to min, min+1, min+2, min+3. Similarly for the UINT256_MAX side.
    40
            // This helps ensure coverage of the min/max values.
    41
            if (x <= 3 && size > x) return min + x;
    42
            if (x >= UINT256_MAX - 3 && size > UINT256_MAX - x) return max - (UINT256_MAX - x);
    43
    44
            // Otherwise, wrap x into the range [min, max], i.e. the range is inclusive.
    45
            if (x > max) {
    46
                uint256 diff = x - max;
    47
                uint256 rem = diff % size;
    48
                if (rem == 0) return max;
    49
                result = min + rem - 1;
    50
            } else if (x < min) {
    51
                uint256 diff = min - x;
    52
                uint256 rem = diff % size;
    53
                if (rem == 0) return min;
    54
                result = max - rem + 1;
    55
            }
    56
        }
    57
    58
        function bound(uint256 x, uint256 min, uint256 max) internal pure virtual returns (uint256 result) {
    59
            result = _bound(x, min, max);
    60
            console2_log_StdUtils("Bound result", result);
    61
        }
    62
    63
        function _bound(int256 x, int256 min, int256 max) internal pure virtual returns (int256 result) {
    64
            require(min <= max, "StdUtils bound(int256,int256,int256): Max is less than min.");
    65
    66
            // Shifting all int256 values to uint256 to use _bound function. The range of two types are:
    67
            // int256 : -(2**255) ~ (2**255 - 1)
    68
            // uint256:     0     ~ (2**256 - 1)
    69
            // So, add 2**255, INT256_MIN_ABS to the integer values.
    70
            //
    71
            // If the given integer value is -2**255, we cannot use `-uint256(-x)` because of the overflow.
    72
            // So, use `~uint256(x) + 1` instead.
    73
            uint256 _x = x < 0 ? (INT256_MIN_ABS - ~uint256(x) - 1) : (uint256(x) + INT256_MIN_ABS);
    74
            uint256 _min = min < 0 ? (INT256_MIN_ABS - ~uint256(min) - 1) : (uint256(min) + INT256_MIN_ABS);
    75
            uint256 _max = max < 0 ? (INT256_MIN_ABS - ~uint256(max) - 1) : (uint256(max) + INT256_MIN_ABS);
    76
    77
            uint256 y = _bound(_x, _min, _max);
    78
    79
            // To move it back to int256 value, subtract INT256_MIN_ABS at here.
    80
            result = y < INT256_MIN_ABS ? int256(~(INT256_MIN_ABS - y) + 1) : int256(y - INT256_MIN_ABS);
    81
        }
    82
    83
        function bound(int256 x, int256 min, int256 max) internal pure virtual returns (int256 result) {
    84
            result = _bound(x, min, max);
    85
            console2_log_StdUtils("Bound result", vm.toString(result));
    86
        }
    87
    88
        function boundPrivateKey(uint256 privateKey) internal pure virtual returns (uint256 result) {
    89
            result = _bound(privateKey, 1, SECP256K1_ORDER - 1);
    90
        }
    91
    92
        function bytesToUint(bytes memory b) internal pure virtual returns (uint256) {
    93
            require(b.length <= 32, "StdUtils bytesToUint(bytes): Bytes length exceeds 32.");
    94
            return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256));
    95
        }
    96
    97
        /// @dev Compute the address a contract will be deployed at for a given deployer address and nonce
    98
        /// @notice adapted from Solmate implementation (https://github.com/Rari-Capital/solmate/blob/main/src/utils/LibRLP.sol)
    99
        function computeCreateAddress(address deployer, uint256 nonce) internal pure virtual returns (address) {
    100
            console2_log_StdUtils("computeCreateAddress is deprecated. Please use vm.computeCreateAddress instead.");
    101
            return vm.computeCreateAddress(deployer, nonce);
    102
        }
    103
    104
        function computeCreate2Address(bytes32 salt, bytes32 initcodeHash, address deployer)
    105
            internal
    106
            pure
    107
            virtual
    108
            returns (address)
    109
        {
    110
            console2_log_StdUtils("computeCreate2Address is deprecated. Please use vm.computeCreate2Address instead.");
    111
            return vm.computeCreate2Address(salt, initcodeHash, deployer);
    112
        }
    113
    114
        /// @dev returns the address of a contract created with CREATE2 using the default CREATE2 deployer
    115
        function computeCreate2Address(bytes32 salt, bytes32 initCodeHash) internal pure returns (address) {
    116
            console2_log_StdUtils("computeCreate2Address is deprecated. Please use vm.computeCreate2Address instead.");
    117
            return vm.computeCreate2Address(salt, initCodeHash);
    118
        }
    119
    120
        /// @dev returns the hash of the init code (creation code + no args) used in CREATE2 with no constructor arguments
    121
        /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode
    122
        function hashInitCode(bytes memory creationCode) internal pure returns (bytes32) {
    123
            return hashInitCode(creationCode, "");
    124
        }
    125
    126
        /// @dev returns the hash of the init code (creation code + ABI-encoded args) used in CREATE2
    127
        /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode
    128
        /// @param args the ABI-encoded arguments to the constructor of C
    129
        function hashInitCode(bytes memory creationCode, bytes memory args) internal pure returns (bytes32) {
    130
            return keccak256(abi.encodePacked(creationCode, args));
    131
        }
    132
    133
        // Performs a single call with Multicall3 to query the ERC-20 token balances of the given addresses.
    134
        function getTokenBalances(address token, address[] memory addresses)
    135
            internal
    136
            virtual
    137
            returns (uint256[] memory balances)
    138
        {
    139
            uint256 tokenCodeSize;
    140
            assembly {
    141
                tokenCodeSize := extcodesize(token)
    142
            }
    143
            require(tokenCodeSize > 0, "StdUtils getTokenBalances(address,address[]): Token address is not a contract.");
    144
    145
            // ABI encode the aggregate call to Multicall3.
    146
            uint256 length = addresses.length;
    147
            IMulticall3.Call[] memory calls = new IMulticall3.Call[](length);
    148
            for (uint256 i = 0; i < length; ++i) {
    149
                // 0x70a08231 = bytes4("balanceOf(address)"))
    150
                calls[i] = IMulticall3.Call({target: token, callData: abi.encodeWithSelector(0x70a08231, (addresses[i]))});
    151
            }
    152
    153
            // Make the aggregate call.
    154
            (, bytes[] memory returnData) = multicall.aggregate(calls);
    155
    156
            // ABI decode the return data and return the balances.
    157
            balances = new uint256[](length);
    158
            for (uint256 i = 0; i < length; ++i) {
    159
                balances[i] = abi.decode(returnData[i], (uint256));
    160
            }
    161
        }
    162
    163
        /*//////////////////////////////////////////////////////////////////////////
    164
                                     PRIVATE FUNCTIONS
    165
        //////////////////////////////////////////////////////////////////////////*/
    166
    167
        function addressFromLast20Bytes(bytes32 bytesValue) private pure returns (address) {
    168
            return address(uint160(uint256(bytesValue)));
    169
        }
    170
    171
        // This section is used to prevent the compilation of console, which shortens the compilation time when console is
    172
        // not used elsewhere. We also trick the compiler into letting us make the console log methods as `pure` to avoid
    173
        // any breaking changes to function signatures.
    174
        function _castLogPayloadViewToPure(function(bytes memory) internal view fnIn)
    175
            internal
    176
            pure
    177
            returns (function(bytes memory) internal pure fnOut)
    178
        {
    179
            assembly {
    180
                fnOut := fnIn
    181
            }
    182
        }
    183
    184
        function _sendLogPayload(bytes memory payload) internal pure {
    185
            _castLogPayloadViewToPure(_sendLogPayloadView)(payload);
    186
        }
    187
    188
        function _sendLogPayloadView(bytes memory payload) private view {
    189
            uint256 payloadLength = payload.length;
    190
            address consoleAddress = CONSOLE2_ADDRESS;
    191
            /// @solidity memory-safe-assembly
    192
            assembly {
    193
                let payloadStart := add(payload, 32)
    194
                let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)
    195
            }
    196
        }
    197
    198
        function console2_log_StdUtils(string memory p0) private pure {
    199
            _sendLogPayload(abi.encodeWithSignature("log(string)", p0));
    200
        }
    201
    202
        function console2_log_StdUtils(string memory p0, uint256 p1) private pure {
    203
            _sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1));
    204
        }
    205
    206
        function console2_log_StdUtils(string memory p0, string memory p1) private pure {
    207
            _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1));
    208
        }
    209
    }
    210
    100.0% lib/forge-std/src/Test.sol
    Lines covered: 1 / 1 (100.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    pragma solidity >=0.6.2 <0.9.0;
    3
    4
    pragma experimental ABIEncoderV2;
    5
    6
    // 💬 ABOUT
    7
    // Forge Std's default Test.
    8
    9
    // 🧩 MODULES
    10
    import {console} from "./console.sol";
    11
    import {console2} from "./console2.sol";
    12
    import {safeconsole} from "./safeconsole.sol";
    13
    import {StdAssertions} from "./StdAssertions.sol";
    14
    import {StdChains} from "./StdChains.sol";
    15
    import {StdCheats} from "./StdCheats.sol";
    16
    import {StdConstants} from "./StdConstants.sol";
    17
    import {stdError} from "./StdError.sol";
    18
    import {StdInvariant} from "./StdInvariant.sol";
    19
    import {stdJson} from "./StdJson.sol";
    20
    import {stdMath} from "./StdMath.sol";
    21
    import {StdStorage, stdStorage} from "./StdStorage.sol";
    22
    import {StdStyle} from "./StdStyle.sol";
    23
    import {stdToml} from "./StdToml.sol";
    24
    import {StdUtils} from "./StdUtils.sol";
    25
    import {Vm} from "./Vm.sol";
    26
    27
    // 📦 BOILERPLATE
    28
    import {TestBase} from "./Base.sol";
    29
    30
    // ⭐️ TEST
    31
    abstract contract Test is TestBase, StdAssertions, StdChains, StdCheats, StdInvariant, StdUtils {
    32
        // Note: IS_TEST() must return true.
    33
        bool public IS_TEST = true;
    34
    }
    35
    0.0% lib/forge-std/src/Vm.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // Automatically @generated by scripts/vm.py. Do not modify manually.
    2
    3
    // SPDX-License-Identifier: MIT OR Apache-2.0
    4
    pragma solidity >=0.6.2 <0.9.0;
    5
    pragma experimental ABIEncoderV2;
    6
    7
    /// The `VmSafe` interface does not allow manipulation of the EVM state or other actions that may
    8
    /// result in Script simulations differing from on-chain execution. It is recommended to only use
    9
    /// these cheats in scripts.
    10
    interface VmSafe {
    11
        /// A modification applied to either `msg.sender` or `tx.origin`. Returned by `readCallers`.
    12
        enum CallerMode {
    13
            // No caller modification is currently active.
    14
            None,
    15
            // A one time broadcast triggered by a `vm.broadcast()` call is currently active.
    16
            Broadcast,
    17
            // A recurrent broadcast triggered by a `vm.startBroadcast()` call is currently active.
    18
            RecurrentBroadcast,
    19
            // A one time prank triggered by a `vm.prank()` call is currently active.
    20
            Prank,
    21
            // A recurrent prank triggered by a `vm.startPrank()` call is currently active.
    22
            RecurrentPrank
    23
        }
    24
    25
        /// The kind of account access that occurred.
    26
        enum AccountAccessKind {
    27
            // The account was called.
    28
            Call,
    29
            // The account was called via delegatecall.
    30
            DelegateCall,
    31
            // The account was called via callcode.
    32
            CallCode,
    33
            // The account was called via staticcall.
    34
            StaticCall,
    35
            // The account was created.
    36
            Create,
    37
            // The account was selfdestructed.
    38
            SelfDestruct,
    39
            // Synthetic access indicating the current context has resumed after a previous sub-context (AccountAccess).
    40
            Resume,
    41
            // The account's balance was read.
    42
            Balance,
    43
            // The account's codesize was read.
    44
            Extcodesize,
    45
            // The account's codehash was read.
    46
            Extcodehash,
    47
            // The account's code was copied.
    48
            Extcodecopy
    49
        }
    50
    51
        /// Forge execution contexts.
    52
        enum ForgeContext {
    53
            // Test group execution context (test, coverage or snapshot).
    54
            TestGroup,
    55
            // `forge test` execution context.
    56
            Test,
    57
            // `forge coverage` execution context.
    58
            Coverage,
    59
            // `forge snapshot` execution context.
    60
            Snapshot,
    61
            // Script group execution context (dry run, broadcast or resume).
    62
            ScriptGroup,
    63
            // `forge script` execution context.
    64
            ScriptDryRun,
    65
            // `forge script --broadcast` execution context.
    66
            ScriptBroadcast,
    67
            // `forge script --resume` execution context.
    68
            ScriptResume,
    69
            // Unknown `forge` execution context.
    70
            Unknown
    71
        }
    72
    73
        /// The transaction type (`txType`) of the broadcast.
    74
        enum BroadcastTxType {
    75
            // Represents a CALL broadcast tx.
    76
            Call,
    77
            // Represents a CREATE broadcast tx.
    78
            Create,
    79
            // Represents a CREATE2 broadcast tx.
    80
            Create2
    81
        }
    82
    83
        /// An Ethereum log. Returned by `getRecordedLogs`.
    84
        struct Log {
    85
            // The topics of the log, including the signature, if any.
    86
            bytes32[] topics;
    87
            // The raw data of the log.
    88
            bytes data;
    89
            // The address of the log's emitter.
    90
            address emitter;
    91
        }
    92
    93
        /// An RPC URL and its alias. Returned by `rpcUrlStructs`.
    94
        struct Rpc {
    95
            // The alias of the RPC URL.
    96
            string key;
    97
            // The RPC URL.
    98
            string url;
    99
        }
    100
    101
        /// An RPC log object. Returned by `eth_getLogs`.
    102
        struct EthGetLogs {
    103
            // The address of the log's emitter.
    104
            address emitter;
    105
            // The topics of the log, including the signature, if any.
    106
            bytes32[] topics;
    107
            // The raw data of the log.
    108
            bytes data;
    109
            // The block hash.
    110
            bytes32 blockHash;
    111
            // The block number.
    112
            uint64 blockNumber;
    113
            // The transaction hash.
    114
            bytes32 transactionHash;
    115
            // The transaction index in the block.
    116
            uint64 transactionIndex;
    117
            // The log index.
    118
            uint256 logIndex;
    119
            // Whether the log was removed.
    120
            bool removed;
    121
        }
    122
    123
        /// A single entry in a directory listing. Returned by `readDir`.
    124
        struct DirEntry {
    125
            // The error message, if any.
    126
            string errorMessage;
    127
            // The path of the entry.
    128
            string path;
    129
            // The depth of the entry.
    130
            uint64 depth;
    131
            // Whether the entry is a directory.
    132
            bool isDir;
    133
            // Whether the entry is a symlink.
    134
            bool isSymlink;
    135
        }
    136
    137
        /// Metadata information about a file.
    138
        /// This structure is returned from the `fsMetadata` function and represents known
    139
        /// metadata about a file such as its permissions, size, modification
    140
        /// times, etc.
    141
        struct FsMetadata {
    142
            // True if this metadata is for a directory.
    143
            bool isDir;
    144
            // True if this metadata is for a symlink.
    145
            bool isSymlink;
    146
            // The size of the file, in bytes, this metadata is for.
    147
            uint256 length;
    148
            // True if this metadata is for a readonly (unwritable) file.
    149
            bool readOnly;
    150
            // The last modification time listed in this metadata.
    151
            uint256 modified;
    152
            // The last access time of this metadata.
    153
            uint256 accessed;
    154
            // The creation time listed in this metadata.
    155
            uint256 created;
    156
        }
    157
    158
        /// A wallet with a public and private key.
    159
        struct Wallet {
    160
            // The wallet's address.
    161
            address addr;
    162
            // The wallet's public key `X`.
    163
            uint256 publicKeyX;
    164
            // The wallet's public key `Y`.
    165
            uint256 publicKeyY;
    166
            // The wallet's private key.
    167
            uint256 privateKey;
    168
        }
    169
    170
        /// The result of a `tryFfi` call.
    171
        struct FfiResult {
    172
            // The exit code of the call.
    173
            int32 exitCode;
    174
            // The optionally hex-decoded `stdout` data.
    175
            bytes stdout;
    176
            // The `stderr` data.
    177
            bytes stderr;
    178
        }
    179
    180
        /// Information on the chain and fork.
    181
        struct ChainInfo {
    182
            // The fork identifier. Set to zero if no fork is active.
    183
            uint256 forkId;
    184
            // The chain ID of the current fork.
    185
            uint256 chainId;
    186
        }
    187
    188
        /// Information about a blockchain.
    189
        struct Chain {
    190
            // The chain name.
    191
            string name;
    192
            // The chain's Chain ID.
    193
            uint256 chainId;
    194
            // The chain's alias. (i.e. what gets specified in `foundry.toml`).
    195
            string chainAlias;
    196
            // A default RPC endpoint for this chain.
    197
            string rpcUrl;
    198
        }
    199
    200
        /// The result of a `stopAndReturnStateDiff` call.
    201
        struct AccountAccess {
    202
            // The chain and fork the access occurred.
    203
            ChainInfo chainInfo;
    204
            // The kind of account access that determines what the account is.
    205
            // If kind is Call, DelegateCall, StaticCall or CallCode, then the account is the callee.
    206
            // If kind is Create, then the account is the newly created account.
    207
            // If kind is SelfDestruct, then the account is the selfdestruct recipient.
    208
            // If kind is a Resume, then account represents a account context that has resumed.
    209
            AccountAccessKind kind;
    210
            // The account that was accessed.
    211
            // It's either the account created, callee or a selfdestruct recipient for CREATE, CALL or SELFDESTRUCT.
    212
            address account;
    213
            // What accessed the account.
    214
            address accessor;
    215
            // If the account was initialized or empty prior to the access.
    216
            // An account is considered initialized if it has code, a
    217
            // non-zero nonce, or a non-zero balance.
    218
            bool initialized;
    219
            // The previous balance of the accessed account.
    220
            uint256 oldBalance;
    221
            // The potential new balance of the accessed account.
    222
            // That is, all balance changes are recorded here, even if reverts occurred.
    223
            uint256 newBalance;
    224
            // Code of the account deployed by CREATE.
    225
            bytes deployedCode;
    226
            // Value passed along with the account access
    227
            uint256 value;
    228
            // Input data provided to the CREATE or CALL
    229
            bytes data;
    230
            // If this access reverted in either the current or parent context.
    231
            bool reverted;
    232
            // An ordered list of storage accesses made during an account access operation.
    233
            StorageAccess[] storageAccesses;
    234
            // Call depth traversed during the recording of state differences
    235
            uint64 depth;
    236
        }
    237
    238
        /// The storage accessed during an `AccountAccess`.
    239
        struct StorageAccess {
    240
            // The account whose storage was accessed.
    241
            address account;
    242
            // The slot that was accessed.
    243
            bytes32 slot;
    244
            // If the access was a write.
    245
            bool isWrite;
    246
            // The previous value of the slot.
    247
            bytes32 previousValue;
    248
            // The new value of the slot.
    249
            bytes32 newValue;
    250
            // If the access was reverted.
    251
            bool reverted;
    252
        }
    253
    254
        /// Gas used. Returned by `lastCallGas`.
    255
        struct Gas {
    256
            // The gas limit of the call.
    257
            uint64 gasLimit;
    258
            // The total gas used.
    259
            uint64 gasTotalUsed;
    260
            // DEPRECATED: The amount of gas used for memory expansion. Ref: <https://github.com/foundry-rs/foundry/pull/7934#pullrequestreview-2069236939>
    261
            uint64 gasMemoryUsed;
    262
            // The amount of gas refunded.
    263
            int64 gasRefunded;
    264
            // The amount of gas remaining.
    265
            uint64 gasRemaining;
    266
        }
    267
    268
        /// The result of the `stopDebugTraceRecording` call
    269
        struct DebugStep {
    270
            // The stack before executing the step of the run.
    271
            // stack\[0\] represents the top of the stack.
    272
            // and only stack data relevant to the opcode execution is contained.
    273
            uint256[] stack;
    274
            // The memory input data before executing the step of the run.
    275
            // only input data relevant to the opcode execution is contained.
    276
            // e.g. for MLOAD, it will have memory\[offset:offset+32\] copied here.
    277
            // the offset value can be get by the stack data.
    278
            bytes memoryInput;
    279
            // The opcode that was accessed.
    280
            uint8 opcode;
    281
            // The call depth of the step.
    282
            uint64 depth;
    283
            // Whether the call end up with out of gas error.
    284
            bool isOutOfGas;
    285
            // The contract address where the opcode is running
    286
            address contractAddr;
    287
        }
    288
    289
        /// Represents a transaction's broadcast details.
    290
        struct BroadcastTxSummary {
    291
            // The hash of the transaction that was broadcasted
    292
            bytes32 txHash;
    293
            // Represent the type of transaction among CALL, CREATE, CREATE2
    294
            BroadcastTxType txType;
    295
            // The address of the contract that was called or created.
    296
            // This is address of the contract that is created if the txType is CREATE or CREATE2.
    297
            address contractAddress;
    298
            // The block number the transaction landed in.
    299
            uint64 blockNumber;
    300
            // Status of the transaction, retrieved from the transaction receipt.
    301
            bool success;
    302
        }
    303
    304
        /// Holds a signed EIP-7702 authorization for an authority account to delegate to an implementation.
    305
        struct SignedDelegation {
    306
            // The y-parity of the recovered secp256k1 signature (0 or 1).
    307
            uint8 v;
    308
            // First 32 bytes of the signature.
    309
            bytes32 r;
    310
            // Second 32 bytes of the signature.
    311
            bytes32 s;
    312
            // The current nonce of the authority account at signing time.
    313
            // Used to ensure signature can't be replayed after account nonce changes.
    314
            uint64 nonce;
    315
            // Address of the contract implementation that will be delegated to.
    316
            // Gets encoded into delegation code: 0xef0100 || implementation.
    317
            address implementation;
    318
        }
    319
    320
        /// Represents a "potential" revert reason from a single subsequent call when using `vm.assumeNoReverts`.
    321
        /// Reverts that match will result in a FOUNDRY::ASSUME rejection, whereas unmatched reverts will be surfaced
    322
        /// as normal.
    323
        struct PotentialRevert {
    324
            // The allowed origin of the revert opcode; address(0) allows reverts from any address
    325
            address reverter;
    326
            // When true, only matches on the beginning of the revert data, otherwise, matches on entire revert data
    327
            bool partialMatch;
    328
            // The data to use to match encountered reverts
    329
            bytes revertData;
    330
        }
    331
    332
        /// An EIP-2930 access list item.
    333
        struct AccessListItem {
    334
            // The address to be added in access list.
    335
            address target;
    336
            // The storage keys to be added in access list.
    337
            bytes32[] storageKeys;
    338
        }
    339
    340
        // ======== Crypto ========
    341
    342
        /// Derives a private key from the name, labels the account with that name, and returns the wallet.
    343
        function createWallet(string calldata walletLabel) external returns (Wallet memory wallet);
    344
    345
        /// Generates a wallet from the private key and returns the wallet.
    346
        function createWallet(uint256 privateKey) external returns (Wallet memory wallet);
    347
    348
        /// Generates a wallet from the private key, labels the account with that name, and returns the wallet.
    349
        function createWallet(uint256 privateKey, string calldata walletLabel) external returns (Wallet memory wallet);
    350
    351
        /// Derive a private key from a provided mnenomic string (or mnenomic file path)
    352
        /// at the derivation path `m/44'/60'/0'/0/{index}`.
    353
        function deriveKey(string calldata mnemonic, uint32 index) external pure returns (uint256 privateKey);
    354
    355
        /// Derive a private key from a provided mnenomic string (or mnenomic file path)
    356
        /// at `{derivationPath}{index}`.
    357
        function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index)
    358
            external
    359
            pure
    360
            returns (uint256 privateKey);
    361
    362
        /// Derive a private key from a provided mnenomic string (or mnenomic file path) in the specified language
    363
        /// at the derivation path `m/44'/60'/0'/0/{index}`.
    364
        function deriveKey(string calldata mnemonic, uint32 index, string calldata language)
    365
            external
    366
            pure
    367
            returns (uint256 privateKey);
    368
    369
        /// Derive a private key from a provided mnenomic string (or mnenomic file path) in the specified language
    370
        /// at `{derivationPath}{index}`.
    371
        function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index, string calldata language)
    372
            external
    373
            pure
    374
            returns (uint256 privateKey);
    375
    376
        /// Derives secp256r1 public key from the provided `privateKey`.
    377
        function publicKeyP256(uint256 privateKey) external pure returns (uint256 publicKeyX, uint256 publicKeyY);
    378
    379
        /// Adds a private key to the local forge wallet and returns the address.
    380
        function rememberKey(uint256 privateKey) external returns (address keyAddr);
    381
    382
        /// Derive a set number of wallets from a mnemonic at the derivation path `m/44'/60'/0'/0/{0..count}`.
    383
        /// The respective private keys are saved to the local forge wallet for later use and their addresses are returned.
    384
        function rememberKeys(string calldata mnemonic, string calldata derivationPath, uint32 count)
    385
            external
    386
            returns (address[] memory keyAddrs);
    387
    388
        /// Derive a set number of wallets from a mnemonic in the specified language at the derivation path `m/44'/60'/0'/0/{0..count}`.
    389
        /// The respective private keys are saved to the local forge wallet for later use and their addresses are returned.
    390
        function rememberKeys(
    391
            string calldata mnemonic,
    392
            string calldata derivationPath,
    393
            string calldata language,
    394
            uint32 count
    395
        ) external returns (address[] memory keyAddrs);
    396
    397
        /// Signs data with a `Wallet`.
    398
        /// Returns a compact signature (`r`, `vs`) as per EIP-2098, where `vs` encodes both the
    399
        /// signature's `s` value, and the recovery id `v` in a single bytes32.
    400
        /// This format reduces the signature size from 65 to 64 bytes.
    401
        function signCompact(Wallet calldata wallet, bytes32 digest) external returns (bytes32 r, bytes32 vs);
    402
    403
        /// Signs `digest` with `privateKey` using the secp256k1 curve.
    404
        /// Returns a compact signature (`r`, `vs`) as per EIP-2098, where `vs` encodes both the
    405
        /// signature's `s` value, and the recovery id `v` in a single bytes32.
    406
        /// This format reduces the signature size from 65 to 64 bytes.
    407
        function signCompact(uint256 privateKey, bytes32 digest) external pure returns (bytes32 r, bytes32 vs);
    408
    409
        /// Signs `digest` with signer provided to script using the secp256k1 curve.
    410
        /// Returns a compact signature (`r`, `vs`) as per EIP-2098, where `vs` encodes both the
    411
        /// signature's `s` value, and the recovery id `v` in a single bytes32.
    412
        /// This format reduces the signature size from 65 to 64 bytes.
    413
        /// If `--sender` is provided, the signer with provided address is used, otherwise,
    414
        /// if exactly one signer is provided to the script, that signer is used.
    415
        /// Raises error if signer passed through `--sender` does not match any unlocked signers or
    416
        /// if `--sender` is not provided and not exactly one signer is passed to the script.
    417
        function signCompact(bytes32 digest) external pure returns (bytes32 r, bytes32 vs);
    418
    419
        /// Signs `digest` with signer provided to script using the secp256k1 curve.
    420
        /// Returns a compact signature (`r`, `vs`) as per EIP-2098, where `vs` encodes both the
    421
        /// signature's `s` value, and the recovery id `v` in a single bytes32.
    422
        /// This format reduces the signature size from 65 to 64 bytes.
    423
        /// Raises error if none of the signers passed into the script have provided address.
    424
        function signCompact(address signer, bytes32 digest) external pure returns (bytes32 r, bytes32 vs);
    425
    426
        /// Signs `digest` with `privateKey` using the secp256r1 curve.
    427
        function signP256(uint256 privateKey, bytes32 digest) external pure returns (bytes32 r, bytes32 s);
    428
    429
        /// Signs data with a `Wallet`.
    430
        function sign(Wallet calldata wallet, bytes32 digest) external returns (uint8 v, bytes32 r, bytes32 s);
    431
    432
        /// Signs `digest` with `privateKey` using the secp256k1 curve.
    433
        function sign(uint256 privateKey, bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s);
    434
    435
        /// Signs `digest` with signer provided to script using the secp256k1 curve.
    436
        /// If `--sender` is provided, the signer with provided address is used, otherwise,
    437
        /// if exactly one signer is provided to the script, that signer is used.
    438
        /// Raises error if signer passed through `--sender` does not match any unlocked signers or
    439
        /// if `--sender` is not provided and not exactly one signer is passed to the script.
    440
        function sign(bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s);
    441
    442
        /// Signs `digest` with signer provided to script using the secp256k1 curve.
    443
        /// Raises error if none of the signers passed into the script have provided address.
    444
        function sign(address signer, bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s);
    445
    446
        // ======== Environment ========
    447
    448
        /// Gets the environment variable `name` and parses it as `address`.
    449
        /// Reverts if the variable was not found or could not be parsed.
    450
        function envAddress(string calldata name) external view returns (address value);
    451
    452
        /// Gets the environment variable `name` and parses it as an array of `address`, delimited by `delim`.
    453
        /// Reverts if the variable was not found or could not be parsed.
    454
        function envAddress(string calldata name, string calldata delim) external view returns (address[] memory value);
    455
    456
        /// Gets the environment variable `name` and parses it as `bool`.
    457
        /// Reverts if the variable was not found or could not be parsed.
    458
        function envBool(string calldata name) external view returns (bool value);
    459
    460
        /// Gets the environment variable `name` and parses it as an array of `bool`, delimited by `delim`.
    461
        /// Reverts if the variable was not found or could not be parsed.
    462
        function envBool(string calldata name, string calldata delim) external view returns (bool[] memory value);
    463
    464
        /// Gets the environment variable `name` and parses it as `bytes32`.
    465
        /// Reverts if the variable was not found or could not be parsed.
    466
        function envBytes32(string calldata name) external view returns (bytes32 value);
    467
    468
        /// Gets the environment variable `name` and parses it as an array of `bytes32`, delimited by `delim`.
    469
        /// Reverts if the variable was not found or could not be parsed.
    470
        function envBytes32(string calldata name, string calldata delim) external view returns (bytes32[] memory value);
    471
    472
        /// Gets the environment variable `name` and parses it as `bytes`.
    473
        /// Reverts if the variable was not found or could not be parsed.
    474
        function envBytes(string calldata name) external view returns (bytes memory value);
    475
    476
        /// Gets the environment variable `name` and parses it as an array of `bytes`, delimited by `delim`.
    477
        /// Reverts if the variable was not found or could not be parsed.
    478
        function envBytes(string calldata name, string calldata delim) external view returns (bytes[] memory value);
    479
    480
        /// Gets the environment variable `name` and returns true if it exists, else returns false.
    481
        function envExists(string calldata name) external view returns (bool result);
    482
    483
        /// Gets the environment variable `name` and parses it as `int256`.
    484
        /// Reverts if the variable was not found or could not be parsed.
    485
        function envInt(string calldata name) external view returns (int256 value);
    486
    487
        /// Gets the environment variable `name` and parses it as an array of `int256`, delimited by `delim`.
    488
        /// Reverts if the variable was not found or could not be parsed.
    489
        function envInt(string calldata name, string calldata delim) external view returns (int256[] memory value);
    490
    491
        /// Gets the environment variable `name` and parses it as `bool`.
    492
        /// Reverts if the variable could not be parsed.
    493
        /// Returns `defaultValue` if the variable was not found.
    494
        function envOr(string calldata name, bool defaultValue) external view returns (bool value);
    495
    496
        /// Gets the environment variable `name` and parses it as `uint256`.
    497
        /// Reverts if the variable could not be parsed.
    498
        /// Returns `defaultValue` if the variable was not found.
    499
        function envOr(string calldata name, uint256 defaultValue) external view returns (uint256 value);
    500
    501
        /// Gets the environment variable `name` and parses it as an array of `address`, delimited by `delim`.
    502
        /// Reverts if the variable could not be parsed.
    503
        /// Returns `defaultValue` if the variable was not found.
    504
        function envOr(string calldata name, string calldata delim, address[] calldata defaultValue)
    505
            external
    506
            view
    507
            returns (address[] memory value);
    508
    509
        /// Gets the environment variable `name` and parses it as an array of `bytes32`, delimited by `delim`.
    510
        /// Reverts if the variable could not be parsed.
    511
        /// Returns `defaultValue` if the variable was not found.
    512
        function envOr(string calldata name, string calldata delim, bytes32[] calldata defaultValue)
    513
            external
    514
            view
    515
            returns (bytes32[] memory value);
    516
    517
        /// Gets the environment variable `name` and parses it as an array of `string`, delimited by `delim`.
    518
        /// Reverts if the variable could not be parsed.
    519
        /// Returns `defaultValue` if the variable was not found.
    520
        function envOr(string calldata name, string calldata delim, string[] calldata defaultValue)
    521
            external
    522
            view
    523
            returns (string[] memory value);
    524
    525
        /// Gets the environment variable `name` and parses it as an array of `bytes`, delimited by `delim`.
    526
        /// Reverts if the variable could not be parsed.
    527
        /// Returns `defaultValue` if the variable was not found.
    528
        function envOr(string calldata name, string calldata delim, bytes[] calldata defaultValue)
    529
            external
    530
            view
    531
            returns (bytes[] memory value);
    532
    533
        /// Gets the environment variable `name` and parses it as `int256`.
    534
        /// Reverts if the variable could not be parsed.
    535
        /// Returns `defaultValue` if the variable was not found.
    536
        function envOr(string calldata name, int256 defaultValue) external view returns (int256 value);
    537
    538
        /// Gets the environment variable `name` and parses it as `address`.
    539
        /// Reverts if the variable could not be parsed.
    540
        /// Returns `defaultValue` if the variable was not found.
    541
        function envOr(string calldata name, address defaultValue) external view returns (address value);
    542
    543
        /// Gets the environment variable `name` and parses it as `bytes32`.
    544
        /// Reverts if the variable could not be parsed.
    545
        /// Returns `defaultValue` if the variable was not found.
    546
        function envOr(string calldata name, bytes32 defaultValue) external view returns (bytes32 value);
    547
    548
        /// Gets the environment variable `name` and parses it as `string`.
    549
        /// Reverts if the variable could not be parsed.
    550
        /// Returns `defaultValue` if the variable was not found.
    551
        function envOr(string calldata name, string calldata defaultValue) external view returns (string memory value);
    552
    553
        /// Gets the environment variable `name` and parses it as `bytes`.
    554
        /// Reverts if the variable could not be parsed.
    555
        /// Returns `defaultValue` if the variable was not found.
    556
        function envOr(string calldata name, bytes calldata defaultValue) external view returns (bytes memory value);
    557
    558
        /// Gets the environment variable `name` and parses it as an array of `bool`, delimited by `delim`.
    559
        /// Reverts if the variable could not be parsed.
    560
        /// Returns `defaultValue` if the variable was not found.
    561
        function envOr(string calldata name, string calldata delim, bool[] calldata defaultValue)
    562
            external
    563
            view
    564
            returns (bool[] memory value);
    565
    566
        /// Gets the environment variable `name` and parses it as an array of `uint256`, delimited by `delim`.
    567
        /// Reverts if the variable could not be parsed.
    568
        /// Returns `defaultValue` if the variable was not found.
    569
        function envOr(string calldata name, string calldata delim, uint256[] calldata defaultValue)
    570
            external
    571
            view
    572
            returns (uint256[] memory value);
    573
    574
        /// Gets the environment variable `name` and parses it as an array of `int256`, delimited by `delim`.
    575
        /// Reverts if the variable could not be parsed.
    576
        /// Returns `defaultValue` if the variable was not found.
    577
        function envOr(string calldata name, string calldata delim, int256[] calldata defaultValue)
    578
            external
    579
            view
    580
            returns (int256[] memory value);
    581
    582
        /// Gets the environment variable `name` and parses it as `string`.
    583
        /// Reverts if the variable was not found or could not be parsed.
    584
        function envString(string calldata name) external view returns (string memory value);
    585
    586
        /// Gets the environment variable `name` and parses it as an array of `string`, delimited by `delim`.
    587
        /// Reverts if the variable was not found or could not be parsed.
    588
        function envString(string calldata name, string calldata delim) external view returns (string[] memory value);
    589
    590
        /// Gets the environment variable `name` and parses it as `uint256`.
    591
        /// Reverts if the variable was not found or could not be parsed.
    592
        function envUint(string calldata name) external view returns (uint256 value);
    593
    594
        /// Gets the environment variable `name` and parses it as an array of `uint256`, delimited by `delim`.
    595
        /// Reverts if the variable was not found or could not be parsed.
    596
        function envUint(string calldata name, string calldata delim) external view returns (uint256[] memory value);
    597
    598
        /// Returns true if `forge` command was executed in given context.
    599
        function isContext(ForgeContext context) external view returns (bool result);
    600
    601
        /// Sets environment variables.
    602
        function setEnv(string calldata name, string calldata value) external;
    603
    604
        // ======== EVM ========
    605
    606
        /// Gets all accessed reads and write slot from a `vm.record` session, for a given address.
    607
        function accesses(address target) external returns (bytes32[] memory readSlots, bytes32[] memory writeSlots);
    608
    609
        /// Gets the address for a given private key.
    610
        function addr(uint256 privateKey) external pure returns (address keyAddr);
    611
    612
        /// Gets all the logs according to specified filter.
    613
        function eth_getLogs(uint256 fromBlock, uint256 toBlock, address target, bytes32[] calldata topics)
    614
            external
    615
            returns (EthGetLogs[] memory logs);
    616
    617
        /// Gets the current `block.blobbasefee`.
    618
        /// You should use this instead of `block.blobbasefee` if you use `vm.blobBaseFee`, as `block.blobbasefee` is assumed to be constant across a transaction,
    619
        /// and as a result will get optimized out by the compiler.
    620
        /// See https://github.com/foundry-rs/foundry/issues/6180
    621
        function getBlobBaseFee() external view returns (uint256 blobBaseFee);
    622
    623
        /// Gets the current `block.number`.
    624
        /// You should use this instead of `block.number` if you use `vm.roll`, as `block.number` is assumed to be constant across a transaction,
    625
        /// and as a result will get optimized out by the compiler.
    626
        /// See https://github.com/foundry-rs/foundry/issues/6180
    627
        function getBlockNumber() external view returns (uint256 height);
    628
    629
        /// Gets the current `block.timestamp`.
    630
        /// You should use this instead of `block.timestamp` if you use `vm.warp`, as `block.timestamp` is assumed to be constant across a transaction,
    631
        /// and as a result will get optimized out by the compiler.
    632
        /// See https://github.com/foundry-rs/foundry/issues/6180
    633
        function getBlockTimestamp() external view returns (uint256 timestamp);
    634
    635
        /// Gets the map key and parent of a mapping at a given slot, for a given address.
    636
        function getMappingKeyAndParentOf(address target, bytes32 elementSlot)
    637
            external
    638
            returns (bool found, bytes32 key, bytes32 parent);
    639
    640
        /// Gets the number of elements in the mapping at the given slot, for a given address.
    641
        function getMappingLength(address target, bytes32 mappingSlot) external returns (uint256 length);
    642
    643
        /// Gets the elements at index idx of the mapping at the given slot, for a given address. The
    644
        /// index must be less than the length of the mapping (i.e. the number of keys in the mapping).
    645
        function getMappingSlotAt(address target, bytes32 mappingSlot, uint256 idx) external returns (bytes32 value);
    646
    647
        /// Gets the nonce of an account.
    648
        function getNonce(address account) external view returns (uint64 nonce);
    649
    650
        /// Get the nonce of a `Wallet`.
    651
        function getNonce(Wallet calldata wallet) external returns (uint64 nonce);
    652
    653
        /// Gets all the recorded logs.
    654
        function getRecordedLogs() external returns (Log[] memory logs);
    655
    656
        /// Returns state diffs from current `vm.startStateDiffRecording` session.
    657
        function getStateDiff() external view returns (string memory diff);
    658
    659
        /// Returns state diffs from current `vm.startStateDiffRecording` session, in json format.
    660
        function getStateDiffJson() external view returns (string memory diff);
    661
    662
        /// Gets the gas used in the last call from the callee perspective.
    663
        function lastCallGas() external view returns (Gas memory gas);
    664
    665
        /// Loads a storage slot from an address.
    666
        function load(address target, bytes32 slot) external view returns (bytes32 data);
    667
    668
        /// Pauses gas metering (i.e. gas usage is not counted). Noop if already paused.
    669
        function pauseGasMetering() external;
    670
    671
        /// Records all storage reads and writes. Use `accesses` to get the recorded data.
    672
        /// Subsequent calls to `record` will clear the previous data.
    673
        function record() external;
    674
    675
        /// Record all the transaction logs.
    676
        function recordLogs() external;
    677
    678
        /// Reset gas metering (i.e. gas usage is set to gas limit).
    679
        function resetGasMetering() external;
    680
    681
        /// Resumes gas metering (i.e. gas usage is counted again). Noop if already on.
    682
        function resumeGasMetering() external;
    683
    684
        /// Performs an Ethereum JSON-RPC request to the current fork URL.
    685
        function rpc(string calldata method, string calldata params) external returns (bytes memory data);
    686
    687
        /// Performs an Ethereum JSON-RPC request to the given endpoint.
    688
        function rpc(string calldata urlOrAlias, string calldata method, string calldata params)
    689
            external
    690
            returns (bytes memory data);
    691
    692
        /// Records the debug trace during the run.
    693
        function startDebugTraceRecording() external;
    694
    695
        /// Starts recording all map SSTOREs for later retrieval.
    696
        function startMappingRecording() external;
    697
    698
        /// Record all account accesses as part of CREATE, CALL or SELFDESTRUCT opcodes in order,
    699
        /// along with the context of the calls
    700
        function startStateDiffRecording() external;
    701
    702
        /// Stop debug trace recording and returns the recorded debug trace.
    703
        function stopAndReturnDebugTraceRecording() external returns (DebugStep[] memory step);
    704
    705
        /// Returns an ordered array of all account accesses from a `vm.startStateDiffRecording` session.
    706
        function stopAndReturnStateDiff() external returns (AccountAccess[] memory accountAccesses);
    707
    708
        /// Stops recording all map SSTOREs for later retrieval and clears the recorded data.
    709
        function stopMappingRecording() external;
    710
    711
        /// Stops recording storage reads and writes.
    712
        function stopRecord() external;
    713
    714
        // ======== Filesystem ========
    715
    716
        /// Closes file for reading, resetting the offset and allowing to read it from beginning with readLine.
    717
        /// `path` is relative to the project root.
    718
        function closeFile(string calldata path) external;
    719
    720
        /// Copies the contents of one file to another. This function will **overwrite** the contents of `to`.
    721
        /// On success, the total number of bytes copied is returned and it is equal to the length of the `to` file as reported by `metadata`.
    722
        /// Both `from` and `to` are relative to the project root.
    723
        function copyFile(string calldata from, string calldata to) external returns (uint64 copied);
    724
    725
        /// Creates a new, empty directory at the provided path.
    726
        /// This cheatcode will revert in the following situations, but is not limited to just these cases:
    727
        /// - User lacks permissions to modify `path`.
    728
        /// - A parent of the given path doesn't exist and `recursive` is false.
    729
        /// - `path` already exists and `recursive` is false.
    730
        /// `path` is relative to the project root.
    731
        function createDir(string calldata path, bool recursive) external;
    732
    733
        /// Deploys a contract from an artifact file. Takes in the relative path to the json file or the path to the
    734
        /// artifact in the form of <path>:<contract>:<version> where <contract> and <version> parts are optional.
    735
        function deployCode(string calldata artifactPath) external returns (address deployedAddress);
    736
    737
        /// Deploys a contract from an artifact file. Takes in the relative path to the json file or the path to the
    738
        /// artifact in the form of <path>:<contract>:<version> where <contract> and <version> parts are optional.
    739
        /// Additionally accepts abi-encoded constructor arguments.
    740
        function deployCode(string calldata artifactPath, bytes calldata constructorArgs)
    741
            external
    742
            returns (address deployedAddress);
    743
    744
        /// Deploys a contract from an artifact file. Takes in the relative path to the json file or the path to the
    745
        /// artifact in the form of <path>:<contract>:<version> where <contract> and <version> parts are optional.
    746
        /// Additionally accepts `msg.value`.
    747
        function deployCode(string calldata artifactPath, uint256 value) external returns (address deployedAddress);
    748
    749
        /// Deploys a contract from an artifact file. Takes in the relative path to the json file or the path to the
    750
        /// artifact in the form of <path>:<contract>:<version> where <contract> and <version> parts are optional.
    751
        /// Additionally accepts abi-encoded constructor arguments and `msg.value`.
    752
        function deployCode(string calldata artifactPath, bytes calldata constructorArgs, uint256 value)
    753
            external
    754
            returns (address deployedAddress);
    755
    756
        /// Deploys a contract from an artifact file, using the CREATE2 salt. Takes in the relative path to the json file or the path to the
    757
        /// artifact in the form of <path>:<contract>:<version> where <contract> and <version> parts are optional.
    758
        function deployCode(string calldata artifactPath, bytes32 salt) external returns (address deployedAddress);
    759
    760
        /// Deploys a contract from an artifact file, using the CREATE2 salt. Takes in the relative path to the json file or the path to the
    761
        /// artifact in the form of <path>:<contract>:<version> where <contract> and <version> parts are optional.
    762
        /// Additionally accepts abi-encoded constructor arguments.
    763
        function deployCode(string calldata artifactPath, bytes calldata constructorArgs, bytes32 salt)
    764
            external
    765
            returns (address deployedAddress);
    766
    767
        /// Deploys a contract from an artifact file, using the CREATE2 salt. Takes in the relative path to the json file or the path to the
    768
        /// artifact in the form of <path>:<contract>:<version> where <contract> and <version> parts are optional.
    769
        /// Additionally accepts `msg.value`.
    770
        function deployCode(string calldata artifactPath, uint256 value, bytes32 salt)
    771
            external
    772
            returns (address deployedAddress);
    773
    774
        /// Deploys a contract from an artifact file, using the CREATE2 salt. Takes in the relative path to the json file or the path to the
    775
        /// artifact in the form of <path>:<contract>:<version> where <contract> and <version> parts are optional.
    776
        /// Additionally accepts abi-encoded constructor arguments and `msg.value`.
    777
        function deployCode(string calldata artifactPath, bytes calldata constructorArgs, uint256 value, bytes32 salt)
    778
            external
    779
            returns (address deployedAddress);
    780
    781
        /// Returns true if the given path points to an existing entity, else returns false.
    782
        function exists(string calldata path) external view returns (bool result);
    783
    784
        /// Performs a foreign function call via the terminal.
    785
        function ffi(string[] calldata commandInput) external returns (bytes memory result);
    786
    787
        /// Given a path, query the file system to get information about a file, directory, etc.
    788
        function fsMetadata(string calldata path) external view returns (FsMetadata memory metadata);
    789
    790
        /// Gets the artifact path from code (aka. creation code).
    791
        function getArtifactPathByCode(bytes calldata code) external view returns (string memory path);
    792
    793
        /// Gets the artifact path from deployed code (aka. runtime code).
    794
        function getArtifactPathByDeployedCode(bytes calldata deployedCode) external view returns (string memory path);
    795
    796
        /// Returns the most recent broadcast for the given contract on `chainId` matching `txType`.
    797
        /// For example:
    798
        /// The most recent deployment can be fetched by passing `txType` as `CREATE` or `CREATE2`.
    799
        /// The most recent call can be fetched by passing `txType` as `CALL`.
    800
        function getBroadcast(string calldata contractName, uint64 chainId, BroadcastTxType txType)
    801
            external
    802
            view
    803
            returns (BroadcastTxSummary memory);
    804
    805
        /// Returns all broadcasts for the given contract on `chainId` with the specified `txType`.
    806
        /// Sorted such that the most recent broadcast is the first element, and the oldest is the last. i.e descending order of BroadcastTxSummary.blockNumber.
    807
        function getBroadcasts(string calldata contractName, uint64 chainId, BroadcastTxType txType)
    808
            external
    809
            view
    810
            returns (BroadcastTxSummary[] memory);
    811
    812
        /// Returns all broadcasts for the given contract on `chainId`.
    813
        /// Sorted such that the most recent broadcast is the first element, and the oldest is the last. i.e descending order of BroadcastTxSummary.blockNumber.
    814
        function getBroadcasts(string calldata contractName, uint64 chainId)
    815
            external
    816
            view
    817
            returns (BroadcastTxSummary[] memory);
    818
    819
        /// Gets the creation bytecode from an artifact file. Takes in the relative path to the json file or the path to the
    820
        /// artifact in the form of <path>:<contract>:<version> where <contract> and <version> parts are optional.
    821
        function getCode(string calldata artifactPath) external view returns (bytes memory creationBytecode);
    822
    823
        /// Gets the deployed bytecode from an artifact file. Takes in the relative path to the json file or the path to the
    824
        /// artifact in the form of <path>:<contract>:<version> where <contract> and <version> parts are optional.
    825
        function getDeployedCode(string calldata artifactPath) external view returns (bytes memory runtimeBytecode);
    826
    827
        /// Returns the most recent deployment for the current `chainId`.
    828
        function getDeployment(string calldata contractName) external view returns (address deployedAddress);
    829
    830
        /// Returns the most recent deployment for the given contract on `chainId`
    831
        function getDeployment(string calldata contractName, uint64 chainId)
    832
            external
    833
            view
    834
            returns (address deployedAddress);
    835
    836
        /// Returns all deployments for the given contract on `chainId`
    837
        /// Sorted in descending order of deployment time i.e descending order of BroadcastTxSummary.blockNumber.
    838
        /// The most recent deployment is the first element, and the oldest is the last.
    839
        function getDeployments(string calldata contractName, uint64 chainId)
    840
            external
    841
            view
    842
            returns (address[] memory deployedAddresses);
    843
    844
        /// Returns true if the path exists on disk and is pointing at a directory, else returns false.
    845
        function isDir(string calldata path) external view returns (bool result);
    846
    847
        /// Returns true if the path exists on disk and is pointing at a regular file, else returns false.
    848
        function isFile(string calldata path) external view returns (bool result);
    849
    850
        /// Get the path of the current project root.
    851
        function projectRoot() external view returns (string memory path);
    852
    853
        /// Prompts the user for a string value in the terminal.
    854
        function prompt(string calldata promptText) external returns (string memory input);
    855
    856
        /// Prompts the user for an address in the terminal.
    857
        function promptAddress(string calldata promptText) external returns (address);
    858
    859
        /// Prompts the user for a hidden string value in the terminal.
    860
        function promptSecret(string calldata promptText) external returns (string memory input);
    861
    862
        /// Prompts the user for hidden uint256 in the terminal (usually pk).
    863
        function promptSecretUint(string calldata promptText) external returns (uint256);
    864
    865
        /// Prompts the user for uint256 in the terminal.
    866
        function promptUint(string calldata promptText) external returns (uint256);
    867
    868
        /// Reads the directory at the given path recursively, up to `maxDepth`.
    869
        /// `maxDepth` defaults to 1, meaning only the direct children of the given directory will be returned.
    870
        /// Follows symbolic links if `followLinks` is true.
    871
        function readDir(string calldata path) external view returns (DirEntry[] memory entries);
    872
    873
        /// See `readDir(string)`.
    874
        function readDir(string calldata path, uint64 maxDepth) external view returns (DirEntry[] memory entries);
    875
    876
        /// See `readDir(string)`.
    877
        function readDir(string calldata path, uint64 maxDepth, bool followLinks)
    878
            external
    879
            view
    880
            returns (DirEntry[] memory entries);
    881
    882
        /// Reads the entire content of file to string. `path` is relative to the project root.
    883
        function readFile(string calldata path) external view returns (string memory data);
    884
    885
        /// Reads the entire content of file as binary. `path` is relative to the project root.
    886
        function readFileBinary(string calldata path) external view returns (bytes memory data);
    887
    888
        /// Reads next line of file to string.
    889
        function readLine(string calldata path) external view returns (string memory line);
    890
    891
        /// Reads a symbolic link, returning the path that the link points to.
    892
        /// This cheatcode will revert in the following situations, but is not limited to just these cases:
    893
        /// - `path` is not a symbolic link.
    894
        /// - `path` does not exist.
    895
        function readLink(string calldata linkPath) external view returns (string memory targetPath);
    896
    897
        /// Removes a directory at the provided path.
    898
        /// This cheatcode will revert in the following situations, but is not limited to just these cases:
    899
        /// - `path` doesn't exist.
    900
        /// - `path` isn't a directory.
    901
        /// - User lacks permissions to modify `path`.
    902
        /// - The directory is not empty and `recursive` is false.
    903
        /// `path` is relative to the project root.
    904
        function removeDir(string calldata path, bool recursive) external;
    905
    906
        /// Removes a file from the filesystem.
    907
        /// This cheatcode will revert in the following situations, but is not limited to just these cases:
    908
        /// - `path` points to a directory.
    909
        /// - The file doesn't exist.
    910
        /// - The user lacks permissions to remove the file.
    911
        /// `path` is relative to the project root.
    912
        function removeFile(string calldata path) external;
    913
    914
        /// Performs a foreign function call via terminal and returns the exit code, stdout, and stderr.
    915
        function tryFfi(string[] calldata commandInput) external returns (FfiResult memory result);
    916
    917
        /// Returns the time since unix epoch in milliseconds.
    918
        function unixTime() external view returns (uint256 milliseconds);
    919
    920
        /// Writes data to file, creating a file if it does not exist, and entirely replacing its contents if it does.
    921
        /// `path` is relative to the project root.
    922
        function writeFile(string calldata path, string calldata data) external;
    923
    924
        /// Writes binary data to a file, creating a file if it does not exist, and entirely replacing its contents if it does.
    925
        /// `path` is relative to the project root.
    926
        function writeFileBinary(string calldata path, bytes calldata data) external;
    927
    928
        /// Writes line to file, creating a file if it does not exist.
    929
        /// `path` is relative to the project root.
    930
        function writeLine(string calldata path, string calldata data) external;
    931
    932
        // ======== JSON ========
    933
    934
        /// Checks if `key` exists in a JSON object.
    935
        function keyExistsJson(string calldata json, string calldata key) external view returns (bool);
    936
    937
        /// Parses a string of JSON data at `key` and coerces it to `address`.
    938
        function parseJsonAddress(string calldata json, string calldata key) external pure returns (address);
    939
    940
        /// Parses a string of JSON data at `key` and coerces it to `address[]`.
    941
        function parseJsonAddressArray(string calldata json, string calldata key)
    942
            external
    943
            pure
    944
            returns (address[] memory);
    945
    946
        /// Parses a string of JSON data at `key` and coerces it to `bool`.
    947
        function parseJsonBool(string calldata json, string calldata key) external pure returns (bool);
    948
    949
        /// Parses a string of JSON data at `key` and coerces it to `bool[]`.
    950
        function parseJsonBoolArray(string calldata json, string calldata key) external pure returns (bool[] memory);
    951
    952
        /// Parses a string of JSON data at `key` and coerces it to `bytes`.
    953
        function parseJsonBytes(string calldata json, string calldata key) external pure returns (bytes memory);
    954
    955
        /// Parses a string of JSON data at `key` and coerces it to `bytes32`.
    956
        function parseJsonBytes32(string calldata json, string calldata key) external pure returns (bytes32);
    957
    958
        /// Parses a string of JSON data at `key` and coerces it to `bytes32[]`.
    959
        function parseJsonBytes32Array(string calldata json, string calldata key)
    960
            external
    961
            pure
    962
            returns (bytes32[] memory);
    963
    964
        /// Parses a string of JSON data at `key` and coerces it to `bytes[]`.
    965
        function parseJsonBytesArray(string calldata json, string calldata key) external pure returns (bytes[] memory);
    966
    967
        /// Parses a string of JSON data at `key` and coerces it to `int256`.
    968
        function parseJsonInt(string calldata json, string calldata key) external pure returns (int256);
    969
    970
        /// Parses a string of JSON data at `key` and coerces it to `int256[]`.
    971
        function parseJsonIntArray(string calldata json, string calldata key) external pure returns (int256[] memory);
    972
    973
        /// Returns an array of all the keys in a JSON object.
    974
        function parseJsonKeys(string calldata json, string calldata key) external pure returns (string[] memory keys);
    975
    976
        /// Parses a string of JSON data at `key` and coerces it to `string`.
    977
        function parseJsonString(string calldata json, string calldata key) external pure returns (string memory);
    978
    979
        /// Parses a string of JSON data at `key` and coerces it to `string[]`.
    980
        function parseJsonStringArray(string calldata json, string calldata key) external pure returns (string[] memory);
    981
    982
        /// Parses a string of JSON data at `key` and coerces it to type array corresponding to `typeDescription`.
    983
        function parseJsonTypeArray(string calldata json, string calldata key, string calldata typeDescription)
    984
            external
    985
            pure
    986
            returns (bytes memory);
    987
    988
        /// Parses a string of JSON data and coerces it to type corresponding to `typeDescription`.
    989
        function parseJsonType(string calldata json, string calldata typeDescription)
    990
            external
    991
            pure
    992
            returns (bytes memory);
    993
    994
        /// Parses a string of JSON data at `key` and coerces it to type corresponding to `typeDescription`.
    995
        function parseJsonType(string calldata json, string calldata key, string calldata typeDescription)
    996
            external
    997
            pure
    998
            returns (bytes memory);
    999
    1000
        /// Parses a string of JSON data at `key` and coerces it to `uint256`.
    1001
        function parseJsonUint(string calldata json, string calldata key) external pure returns (uint256);
    1002
    1003
        /// Parses a string of JSON data at `key` and coerces it to `uint256[]`.
    1004
        function parseJsonUintArray(string calldata json, string calldata key) external pure returns (uint256[] memory);
    1005
    1006
        /// ABI-encodes a JSON object.
    1007
        function parseJson(string calldata json) external pure returns (bytes memory abiEncodedData);
    1008
    1009
        /// ABI-encodes a JSON object at `key`.
    1010
        function parseJson(string calldata json, string calldata key) external pure returns (bytes memory abiEncodedData);
    1011
    1012
        /// See `serializeJson`.
    1013
        function serializeAddress(string calldata objectKey, string calldata valueKey, address value)
    1014
            external
    1015
            returns (string memory json);
    1016
    1017
        /// See `serializeJson`.
    1018
        function serializeAddress(string calldata objectKey, string calldata valueKey, address[] calldata values)
    1019
            external
    1020
            returns (string memory json);
    1021
    1022
        /// See `serializeJson`.
    1023
        function serializeBool(string calldata objectKey, string calldata valueKey, bool value)
    1024
            external
    1025
            returns (string memory json);
    1026
    1027
        /// See `serializeJson`.
    1028
        function serializeBool(string calldata objectKey, string calldata valueKey, bool[] calldata values)
    1029
            external
    1030
            returns (string memory json);
    1031
    1032
        /// See `serializeJson`.
    1033
        function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32 value)
    1034
            external
    1035
            returns (string memory json);
    1036
    1037
        /// See `serializeJson`.
    1038
        function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32[] calldata values)
    1039
            external
    1040
            returns (string memory json);
    1041
    1042
        /// See `serializeJson`.
    1043
        function serializeBytes(string calldata objectKey, string calldata valueKey, bytes calldata value)
    1044
            external
    1045
            returns (string memory json);
    1046
    1047
        /// See `serializeJson`.
    1048
        function serializeBytes(string calldata objectKey, string calldata valueKey, bytes[] calldata values)
    1049
            external
    1050
            returns (string memory json);
    1051
    1052
        /// See `serializeJson`.
    1053
        function serializeInt(string calldata objectKey, string calldata valueKey, int256 value)
    1054
            external
    1055
            returns (string memory json);
    1056
    1057
        /// See `serializeJson`.
    1058
        function serializeInt(string calldata objectKey, string calldata valueKey, int256[] calldata values)
    1059
            external
    1060
            returns (string memory json);
    1061
    1062
        /// Serializes a key and value to a JSON object stored in-memory that can be later written to a file.
    1063
        /// Returns the stringified version of the specific JSON file up to that moment.
    1064
        function serializeJson(string calldata objectKey, string calldata value) external returns (string memory json);
    1065
    1066
        /// See `serializeJson`.
    1067
        function serializeJsonType(string calldata typeDescription, bytes calldata value)
    1068
            external
    1069
            pure
    1070
            returns (string memory json);
    1071
    1072
        /// See `serializeJson`.
    1073
        function serializeJsonType(
    1074
            string calldata objectKey,
    1075
            string calldata valueKey,
    1076
            string calldata typeDescription,
    1077
            bytes calldata value
    1078
        ) external returns (string memory json);
    1079
    1080
        /// See `serializeJson`.
    1081
        function serializeString(string calldata objectKey, string calldata valueKey, string calldata value)
    1082
            external
    1083
            returns (string memory json);
    1084
    1085
        /// See `serializeJson`.
    1086
        function serializeString(string calldata objectKey, string calldata valueKey, string[] calldata values)
    1087
            external
    1088
            returns (string memory json);
    1089
    1090
        /// See `serializeJson`.
    1091
        function serializeUintToHex(string calldata objectKey, string calldata valueKey, uint256 value)
    1092
            external
    1093
            returns (string memory json);
    1094
    1095
        /// See `serializeJson`.
    1096
        function serializeUint(string calldata objectKey, string calldata valueKey, uint256 value)
    1097
            external
    1098
            returns (string memory json);
    1099
    1100
        /// See `serializeJson`.
    1101
        function serializeUint(string calldata objectKey, string calldata valueKey, uint256[] calldata values)
    1102
            external
    1103
            returns (string memory json);
    1104
    1105
        /// Write a serialized JSON object to a file. If the file exists, it will be overwritten.
    1106
        function writeJson(string calldata json, string calldata path) external;
    1107
    1108
        /// Write a serialized JSON object to an **existing** JSON file, replacing a value with key = <value_key.>
    1109
        /// This is useful to replace a specific value of a JSON file, without having to parse the entire thing.
    1110
        function writeJson(string calldata json, string calldata path, string calldata valueKey) external;
    1111
    1112
        /// Checks if `key` exists in a JSON object
    1113
        /// `keyExists` is being deprecated in favor of `keyExistsJson`. It will be removed in future versions.
    1114
        function keyExists(string calldata json, string calldata key) external view returns (bool);
    1115
    1116
        // ======== Scripting ========
    1117
    1118
        /// Attach an EIP-4844 blob to the next call
    1119
        function attachBlob(bytes calldata blob) external;
    1120
    1121
        /// Designate the next call as an EIP-7702 transaction
    1122
        function attachDelegation(SignedDelegation calldata signedDelegation) external;
    1123
    1124
        /// Designate the next call as an EIP-7702 transaction, with optional cross-chain validity.
    1125
        function attachDelegation(SignedDelegation calldata signedDelegation, bool crossChain) external;
    1126
    1127
        /// Takes a signed transaction and broadcasts it to the network.
    1128
        function broadcastRawTransaction(bytes calldata data) external;
    1129
    1130
        /// Has the next call (at this call depth only) create transactions that can later be signed and sent onchain.
    1131
        /// Broadcasting address is determined by checking the following in order:
    1132
        /// 1. If `--sender` argument was provided, that address is used.
    1133
        /// 2. If exactly one signer (e.g. private key, hw wallet, keystore) is set when `forge broadcast` is invoked, that signer is used.
    1134
        /// 3. Otherwise, default foundry sender (1804c8AB1F12E6bbf3894d4083f33e07309d1f38) is used.
    1135
        function broadcast() external;
    1136
    1137
        /// Has the next call (at this call depth only) create a transaction with the address provided
    1138
        /// as the sender that can later be signed and sent onchain.
    1139
        function broadcast(address signer) external;
    1140
    1141
        /// Has the next call (at this call depth only) create a transaction with the private key
    1142
        /// provided as the sender that can later be signed and sent onchain.
    1143
        function broadcast(uint256 privateKey) external;
    1144
    1145
        /// Returns addresses of available unlocked wallets in the script environment.
    1146
        function getWallets() external returns (address[] memory wallets);
    1147
    1148
        /// Sign an EIP-7702 authorization and designate the next call as an EIP-7702 transaction
    1149
        function signAndAttachDelegation(address implementation, uint256 privateKey)
    1150
            external
    1151
            returns (SignedDelegation memory signedDelegation);
    1152
    1153
        /// Sign an EIP-7702 authorization and designate the next call as an EIP-7702 transaction for specific nonce
    1154
        function signAndAttachDelegation(address implementation, uint256 privateKey, uint64 nonce)
    1155
            external
    1156
            returns (SignedDelegation memory signedDelegation);
    1157
    1158
        /// Sign an EIP-7702 authorization and designate the next call as an EIP-7702 transaction, with optional cross-chain validity.
    1159
        function signAndAttachDelegation(address implementation, uint256 privateKey, bool crossChain)
    1160
            external
    1161
            returns (SignedDelegation memory signedDelegation);
    1162
    1163
        /// Sign an EIP-7702 authorization for delegation
    1164
        function signDelegation(address implementation, uint256 privateKey)
    1165
            external
    1166
            returns (SignedDelegation memory signedDelegation);
    1167
    1168
        /// Sign an EIP-7702 authorization for delegation for specific nonce
    1169
        function signDelegation(address implementation, uint256 privateKey, uint64 nonce)
    1170
            external
    1171
            returns (SignedDelegation memory signedDelegation);
    1172
    1173
        /// Sign an EIP-7702 authorization for delegation, with optional cross-chain validity.
    1174
        function signDelegation(address implementation, uint256 privateKey, bool crossChain)
    1175
            external
    1176
            returns (SignedDelegation memory signedDelegation);
    1177
    1178
        /// Has all subsequent calls (at this call depth only) create transactions that can later be signed and sent onchain.
    1179
        /// Broadcasting address is determined by checking the following in order:
    1180
        /// 1. If `--sender` argument was provided, that address is used.
    1181
        /// 2. If exactly one signer (e.g. private key, hw wallet, keystore) is set when `forge broadcast` is invoked, that signer is used.
    1182
        /// 3. Otherwise, default foundry sender (1804c8AB1F12E6bbf3894d4083f33e07309d1f38) is used.
    1183
        function startBroadcast() external;
    1184
    1185
        /// Has all subsequent calls (at this call depth only) create transactions with the address
    1186
        /// provided that can later be signed and sent onchain.
    1187
        function startBroadcast(address signer) external;
    1188
    1189
        /// Has all subsequent calls (at this call depth only) create transactions with the private key
    1190
        /// provided that can later be signed and sent onchain.
    1191
        function startBroadcast(uint256 privateKey) external;
    1192
    1193
        /// Stops collecting onchain transactions.
    1194
        function stopBroadcast() external;
    1195
    1196
        // ======== String ========
    1197
    1198
        /// Returns true if `search` is found in `subject`, false otherwise.
    1199
        function contains(string calldata subject, string calldata search) external returns (bool result);
    1200
    1201
        /// Returns the index of the first occurrence of a `key` in an `input` string.
    1202
        /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `key` is not found.
    1203
        /// Returns 0 in case of an empty `key`.
    1204
        function indexOf(string calldata input, string calldata key) external pure returns (uint256);
    1205
    1206
        /// Parses the given `string` into an `address`.
    1207
        function parseAddress(string calldata stringifiedValue) external pure returns (address parsedValue);
    1208
    1209
        /// Parses the given `string` into a `bool`.
    1210
        function parseBool(string calldata stringifiedValue) external pure returns (bool parsedValue);
    1211
    1212
        /// Parses the given `string` into `bytes`.
    1213
        function parseBytes(string calldata stringifiedValue) external pure returns (bytes memory parsedValue);
    1214
    1215
        /// Parses the given `string` into a `bytes32`.
    1216
        function parseBytes32(string calldata stringifiedValue) external pure returns (bytes32 parsedValue);
    1217
    1218
        /// Parses the given `string` into a `int256`.
    1219
        function parseInt(string calldata stringifiedValue) external pure returns (int256 parsedValue);
    1220
    1221
        /// Parses the given `string` into a `uint256`.
    1222
        function parseUint(string calldata stringifiedValue) external pure returns (uint256 parsedValue);
    1223
    1224
        /// Replaces occurrences of `from` in the given `string` with `to`.
    1225
        function replace(string calldata input, string calldata from, string calldata to)
    1226
            external
    1227
            pure
    1228
            returns (string memory output);
    1229
    1230
        /// Splits the given `string` into an array of strings divided by the `delimiter`.
    1231
        function split(string calldata input, string calldata delimiter) external pure returns (string[] memory outputs);
    1232
    1233
        /// Converts the given `string` value to Lowercase.
    1234
        function toLowercase(string calldata input) external pure returns (string memory output);
    1235
    1236
        /// Converts the given value to a `string`.
    1237
        function toString(address value) external pure returns (string memory stringifiedValue);
    1238
    1239
        /// Converts the given value to a `string`.
    1240
        function toString(bytes calldata value) external pure returns (string memory stringifiedValue);
    1241
    1242
        /// Converts the given value to a `string`.
    1243
        function toString(bytes32 value) external pure returns (string memory stringifiedValue);
    1244
    1245
        /// Converts the given value to a `string`.
    1246
        function toString(bool value) external pure returns (string memory stringifiedValue);
    1247
    1248
        /// Converts the given value to a `string`.
    1249
        function toString(uint256 value) external pure returns (string memory stringifiedValue);
    1250
    1251
        /// Converts the given value to a `string`.
    1252
        function toString(int256 value) external pure returns (string memory stringifiedValue);
    1253
    1254
        /// Converts the given `string` value to Uppercase.
    1255
        function toUppercase(string calldata input) external pure returns (string memory output);
    1256
    1257
        /// Trims leading and trailing whitespace from the given `string` value.
    1258
        function trim(string calldata input) external pure returns (string memory output);
    1259
    1260
        // ======== Testing ========
    1261
    1262
        /// Compares two `uint256` values. Expects difference to be less than or equal to `maxDelta`.
    1263
        /// Formats values with decimals in failure message.
    1264
        function assertApproxEqAbsDecimal(uint256 left, uint256 right, uint256 maxDelta, uint256 decimals) external pure;
    1265
    1266
        /// Compares two `uint256` values. Expects difference to be less than or equal to `maxDelta`.
    1267
        /// Formats values with decimals in failure message. Includes error message into revert string on failure.
    1268
        function assertApproxEqAbsDecimal(
    1269
            uint256 left,
    1270
            uint256 right,
    1271
            uint256 maxDelta,
    1272
            uint256 decimals,
    1273
            string calldata error
    1274
        ) external pure;
    1275
    1276
        /// Compares two `int256` values. Expects difference to be less than or equal to `maxDelta`.
    1277
        /// Formats values with decimals in failure message.
    1278
        function assertApproxEqAbsDecimal(int256 left, int256 right, uint256 maxDelta, uint256 decimals) external pure;
    1279
    1280
        /// Compares two `int256` values. Expects difference to be less than or equal to `maxDelta`.
    1281
        /// Formats values with decimals in failure message. Includes error message into revert string on failure.
    1282
        function assertApproxEqAbsDecimal(
    1283
            int256 left,
    1284
            int256 right,
    1285
            uint256 maxDelta,
    1286
            uint256 decimals,
    1287
            string calldata error
    1288
        ) external pure;
    1289
    1290
        /// Compares two `uint256` values. Expects difference to be less than or equal to `maxDelta`.
    1291
        function assertApproxEqAbs(uint256 left, uint256 right, uint256 maxDelta) external pure;
    1292
    1293
        /// Compares two `uint256` values. Expects difference to be less than or equal to `maxDelta`.
    1294
        /// Includes error message into revert string on failure.
    1295
        function assertApproxEqAbs(uint256 left, uint256 right, uint256 maxDelta, string calldata error) external pure;
    1296
    1297
        /// Compares two `int256` values. Expects difference to be less than or equal to `maxDelta`.
    1298
        function assertApproxEqAbs(int256 left, int256 right, uint256 maxDelta) external pure;
    1299
    1300
        /// Compares two `int256` values. Expects difference to be less than or equal to `maxDelta`.
    1301
        /// Includes error message into revert string on failure.
    1302
        function assertApproxEqAbs(int256 left, int256 right, uint256 maxDelta, string calldata error) external pure;
    1303
    1304
        /// Compares two `uint256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`.
    1305
        /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100%
    1306
        /// Formats values with decimals in failure message.
    1307
        function assertApproxEqRelDecimal(uint256 left, uint256 right, uint256 maxPercentDelta, uint256 decimals)
    1308
            external
    1309
            pure;
    1310
    1311
        /// Compares two `uint256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`.
    1312
        /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100%
    1313
        /// Formats values with decimals in failure message. Includes error message into revert string on failure.
    1314
        function assertApproxEqRelDecimal(
    1315
            uint256 left,
    1316
            uint256 right,
    1317
            uint256 maxPercentDelta,
    1318
            uint256 decimals,
    1319
            string calldata error
    1320
        ) external pure;
    1321
    1322
        /// Compares two `int256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`.
    1323
        /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100%
    1324
        /// Formats values with decimals in failure message.
    1325
        function assertApproxEqRelDecimal(int256 left, int256 right, uint256 maxPercentDelta, uint256 decimals)
    1326
            external
    1327
            pure;
    1328
    1329
        /// Compares two `int256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`.
    1330
        /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100%
    1331
        /// Formats values with decimals in failure message. Includes error message into revert string on failure.
    1332
        function assertApproxEqRelDecimal(
    1333
            int256 left,
    1334
            int256 right,
    1335
            uint256 maxPercentDelta,
    1336
            uint256 decimals,
    1337
            string calldata error
    1338
        ) external pure;
    1339
    1340
        /// Compares two `uint256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`.
    1341
        /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100%
    1342
        function assertApproxEqRel(uint256 left, uint256 right, uint256 maxPercentDelta) external pure;
    1343
    1344
        /// Compares two `uint256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`.
    1345
        /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100%
    1346
        /// Includes error message into revert string on failure.
    1347
        function assertApproxEqRel(uint256 left, uint256 right, uint256 maxPercentDelta, string calldata error)
    1348
            external
    1349
            pure;
    1350
    1351
        /// Compares two `int256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`.
    1352
        /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100%
    1353
        function assertApproxEqRel(int256 left, int256 right, uint256 maxPercentDelta) external pure;
    1354
    1355
        /// Compares two `int256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`.
    1356
        /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100%
    1357
        /// Includes error message into revert string on failure.
    1358
        function assertApproxEqRel(int256 left, int256 right, uint256 maxPercentDelta, string calldata error)
    1359
            external
    1360
            pure;
    1361
    1362
        /// Asserts that two `uint256` values are equal, formatting them with decimals in failure message.
    1363
        function assertEqDecimal(uint256 left, uint256 right, uint256 decimals) external pure;
    1364
    1365
        /// Asserts that two `uint256` values are equal, formatting them with decimals in failure message.
    1366
        /// Includes error message into revert string on failure.
    1367
        function assertEqDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure;
    1368
    1369
        /// Asserts that two `int256` values are equal, formatting them with decimals in failure message.
    1370
        function assertEqDecimal(int256 left, int256 right, uint256 decimals) external pure;
    1371
    1372
        /// Asserts that two `int256` values are equal, formatting them with decimals in failure message.
    1373
        /// Includes error message into revert string on failure.
    1374
        function assertEqDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure;
    1375
    1376
        /// Asserts that two `bool` values are equal.
    1377
        function assertEq(bool left, bool right) external pure;
    1378
    1379
        /// Asserts that two `bool` values are equal and includes error message into revert string on failure.
    1380
        function assertEq(bool left, bool right, string calldata error) external pure;
    1381
    1382
        /// Asserts that two `string` values are equal.
    1383
        function assertEq(string calldata left, string calldata right) external pure;
    1384
    1385
        /// Asserts that two `string` values are equal and includes error message into revert string on failure.
    1386
        function assertEq(string calldata left, string calldata right, string calldata error) external pure;
    1387
    1388
        /// Asserts that two `bytes` values are equal.
    1389
        function assertEq(bytes calldata left, bytes calldata right) external pure;
    1390
    1391
        /// Asserts that two `bytes` values are equal and includes error message into revert string on failure.
    1392
        function assertEq(bytes calldata left, bytes calldata right, string calldata error) external pure;
    1393
    1394
        /// Asserts that two arrays of `bool` values are equal.
    1395
        function assertEq(bool[] calldata left, bool[] calldata right) external pure;
    1396
    1397
        /// Asserts that two arrays of `bool` values are equal and includes error message into revert string on failure.
    1398
        function assertEq(bool[] calldata left, bool[] calldata right, string calldata error) external pure;
    1399
    1400
        /// Asserts that two arrays of `uint256 values are equal.
    1401
        function assertEq(uint256[] calldata left, uint256[] calldata right) external pure;
    1402
    1403
        /// Asserts that two arrays of `uint256` values are equal and includes error message into revert string on failure.
    1404
        function assertEq(uint256[] calldata left, uint256[] calldata right, string calldata error) external pure;
    1405
    1406
        /// Asserts that two arrays of `int256` values are equal.
    1407
        function assertEq(int256[] calldata left, int256[] calldata right) external pure;
    1408
    1409
        /// Asserts that two arrays of `int256` values are equal and includes error message into revert string on failure.
    1410
        function assertEq(int256[] calldata left, int256[] calldata right, string calldata error) external pure;
    1411
    1412
        /// Asserts that two `uint256` values are equal.
    1413
        function assertEq(uint256 left, uint256 right) external pure;
    1414
    1415
        /// Asserts that two arrays of `address` values are equal.
    1416
        function assertEq(address[] calldata left, address[] calldata right) external pure;
    1417
    1418
        /// Asserts that two arrays of `address` values are equal and includes error message into revert string on failure.
    1419
        function assertEq(address[] calldata left, address[] calldata right, string calldata error) external pure;
    1420
    1421
        /// Asserts that two arrays of `bytes32` values are equal.
    1422
        function assertEq(bytes32[] calldata left, bytes32[] calldata right) external pure;
    1423
    1424
        /// Asserts that two arrays of `bytes32` values are equal and includes error message into revert string on failure.
    1425
        function assertEq(bytes32[] calldata left, bytes32[] calldata right, string calldata error) external pure;
    1426
    1427
        /// Asserts that two arrays of `string` values are equal.
    1428
        function assertEq(string[] calldata left, string[] calldata right) external pure;
    1429
    1430
        /// Asserts that two arrays of `string` values are equal and includes error message into revert string on failure.
    1431
        function assertEq(string[] calldata left, string[] calldata right, string calldata error) external pure;
    1432
    1433
        /// Asserts that two arrays of `bytes` values are equal.
    1434
        function assertEq(bytes[] calldata left, bytes[] calldata right) external pure;
    1435
    1436
        /// Asserts that two arrays of `bytes` values are equal and includes error message into revert string on failure.
    1437
        function assertEq(bytes[] calldata left, bytes[] calldata right, string calldata error) external pure;
    1438
    1439
        /// Asserts that two `uint256` values are equal and includes error message into revert string on failure.
    1440
        function assertEq(uint256 left, uint256 right, string calldata error) external pure;
    1441
    1442
        /// Asserts that two `int256` values are equal.
    1443
        function assertEq(int256 left, int256 right) external pure;
    1444
    1445
        /// Asserts that two `int256` values are equal and includes error message into revert string on failure.
    1446
        function assertEq(int256 left, int256 right, string calldata error) external pure;
    1447
    1448
        /// Asserts that two `address` values are equal.
    1449
        function assertEq(address left, address right) external pure;
    1450
    1451
        /// Asserts that two `address` values are equal and includes error message into revert string on failure.
    1452
        function assertEq(address left, address right, string calldata error) external pure;
    1453
    1454
        /// Asserts that two `bytes32` values are equal.
    1455
        function assertEq(bytes32 left, bytes32 right) external pure;
    1456
    1457
        /// Asserts that two `bytes32` values are equal and includes error message into revert string on failure.
    1458
        function assertEq(bytes32 left, bytes32 right, string calldata error) external pure;
    1459
    1460
        /// Asserts that the given condition is false.
    1461
        function assertFalse(bool condition) external pure;
    1462
    1463
        /// Asserts that the given condition is false and includes error message into revert string on failure.
    1464
        function assertFalse(bool condition, string calldata error) external pure;
    1465
    1466
        /// Compares two `uint256` values. Expects first value to be greater than or equal to second.
    1467
        /// Formats values with decimals in failure message.
    1468
        function assertGeDecimal(uint256 left, uint256 right, uint256 decimals) external pure;
    1469
    1470
        /// Compares two `uint256` values. Expects first value to be greater than or equal to second.
    1471
        /// Formats values with decimals in failure message. Includes error message into revert string on failure.
    1472
        function assertGeDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure;
    1473
    1474
        /// Compares two `int256` values. Expects first value to be greater than or equal to second.
    1475
        /// Formats values with decimals in failure message.
    1476
        function assertGeDecimal(int256 left, int256 right, uint256 decimals) external pure;
    1477
    1478
        /// Compares two `int256` values. Expects first value to be greater than or equal to second.
    1479
        /// Formats values with decimals in failure message. Includes error message into revert string on failure.
    1480
        function assertGeDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure;
    1481
    1482
        /// Compares two `uint256` values. Expects first value to be greater than or equal to second.
    1483
        function assertGe(uint256 left, uint256 right) external pure;
    1484
    1485
        /// Compares two `uint256` values. Expects first value to be greater than or equal to second.
    1486
        /// Includes error message into revert string on failure.
    1487
        function assertGe(uint256 left, uint256 right, string calldata error) external pure;
    1488
    1489
        /// Compares two `int256` values. Expects first value to be greater than or equal to second.
    1490
        function assertGe(int256 left, int256 right) external pure;
    1491
    1492
        /// Compares two `int256` values. Expects first value to be greater than or equal to second.
    1493
        /// Includes error message into revert string on failure.
    1494
        function assertGe(int256 left, int256 right, string calldata error) external pure;
    1495
    1496
        /// Compares two `uint256` values. Expects first value to be greater than second.
    1497
        /// Formats values with decimals in failure message.
    1498
        function assertGtDecimal(uint256 left, uint256 right, uint256 decimals) external pure;
    1499
    1500
        /// Compares two `uint256` values. Expects first value to be greater than second.
    1501
        /// Formats values with decimals in failure message. Includes error message into revert string on failure.
    1502
        function assertGtDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure;
    1503
    1504
        /// Compares two `int256` values. Expects first value to be greater than second.
    1505
        /// Formats values with decimals in failure message.
    1506
        function assertGtDecimal(int256 left, int256 right, uint256 decimals) external pure;
    1507
    1508
        /// Compares two `int256` values. Expects first value to be greater than second.
    1509
        /// Formats values with decimals in failure message. Includes error message into revert string on failure.
    1510
        function assertGtDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure;
    1511
    1512
        /// Compares two `uint256` values. Expects first value to be greater than second.
    1513
        function assertGt(uint256 left, uint256 right) external pure;
    1514
    1515
        /// Compares two `uint256` values. Expects first value to be greater than second.
    1516
        /// Includes error message into revert string on failure.
    1517
        function assertGt(uint256 left, uint256 right, string calldata error) external pure;
    1518
    1519
        /// Compares two `int256` values. Expects first value to be greater than second.
    1520
        function assertGt(int256 left, int256 right) external pure;
    1521
    1522
        /// Compares two `int256` values. Expects first value to be greater than second.
    1523
        /// Includes error message into revert string on failure.
    1524
        function assertGt(int256 left, int256 right, string calldata error) external pure;
    1525
    1526
        /// Compares two `uint256` values. Expects first value to be less than or equal to second.
    1527
        /// Formats values with decimals in failure message.
    1528
        function assertLeDecimal(uint256 left, uint256 right, uint256 decimals) external pure;
    1529
    1530
        /// Compares two `uint256` values. Expects first value to be less than or equal to second.
    1531
        /// Formats values with decimals in failure message. Includes error message into revert string on failure.
    1532
        function assertLeDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure;
    1533
    1534
        /// Compares two `int256` values. Expects first value to be less than or equal to second.
    1535
        /// Formats values with decimals in failure message.
    1536
        function assertLeDecimal(int256 left, int256 right, uint256 decimals) external pure;
    1537
    1538
        /// Compares two `int256` values. Expects first value to be less than or equal to second.
    1539
        /// Formats values with decimals in failure message. Includes error message into revert string on failure.
    1540
        function assertLeDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure;
    1541
    1542
        /// Compares two `uint256` values. Expects first value to be less than or equal to second.
    1543
        function assertLe(uint256 left, uint256 right) external pure;
    1544
    1545
        /// Compares two `uint256` values. Expects first value to be less than or equal to second.
    1546
        /// Includes error message into revert string on failure.
    1547
        function assertLe(uint256 left, uint256 right, string calldata error) external pure;
    1548
    1549
        /// Compares two `int256` values. Expects first value to be less than or equal to second.
    1550
        function assertLe(int256 left, int256 right) external pure;
    1551
    1552
        /// Compares two `int256` values. Expects first value to be less than or equal to second.
    1553
        /// Includes error message into revert string on failure.
    1554
        function assertLe(int256 left, int256 right, string calldata error) external pure;
    1555
    1556
        /// Compares two `uint256` values. Expects first value to be less than second.
    1557
        /// Formats values with decimals in failure message.
    1558
        function assertLtDecimal(uint256 left, uint256 right, uint256 decimals) external pure;
    1559
    1560
        /// Compares two `uint256` values. Expects first value to be less than second.
    1561
        /// Formats values with decimals in failure message. Includes error message into revert string on failure.
    1562
        function assertLtDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure;
    1563
    1564
        /// Compares two `int256` values. Expects first value to be less than second.
    1565
        /// Formats values with decimals in failure message.
    1566
        function assertLtDecimal(int256 left, int256 right, uint256 decimals) external pure;
    1567
    1568
        /// Compares two `int256` values. Expects first value to be less than second.
    1569
        /// Formats values with decimals in failure message. Includes error message into revert string on failure.
    1570
        function assertLtDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure;
    1571
    1572
        /// Compares two `uint256` values. Expects first value to be less than second.
    1573
        function assertLt(uint256 left, uint256 right) external pure;
    1574
    1575
        /// Compares two `uint256` values. Expects first value to be less than second.
    1576
        /// Includes error message into revert string on failure.
    1577
        function assertLt(uint256 left, uint256 right, string calldata error) external pure;
    1578
    1579
        /// Compares two `int256` values. Expects first value to be less than second.
    1580
        function assertLt(int256 left, int256 right) external pure;
    1581
    1582
        /// Compares two `int256` values. Expects first value to be less than second.
    1583
        /// Includes error message into revert string on failure.
    1584
        function assertLt(int256 left, int256 right, string calldata error) external pure;
    1585
    1586
        /// Asserts that two `uint256` values are not equal, formatting them with decimals in failure message.
    1587
        function assertNotEqDecimal(uint256 left, uint256 right, uint256 decimals) external pure;
    1588
    1589
        /// Asserts that two `uint256` values are not equal, formatting them with decimals in failure message.
    1590
        /// Includes error message into revert string on failure.
    1591
        function assertNotEqDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure;
    1592
    1593
        /// Asserts that two `int256` values are not equal, formatting them with decimals in failure message.
    1594
        function assertNotEqDecimal(int256 left, int256 right, uint256 decimals) external pure;
    1595
    1596
        /// Asserts that two `int256` values are not equal, formatting them with decimals in failure message.
    1597
        /// Includes error message into revert string on failure.
    1598
        function assertNotEqDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure;
    1599
    1600
        /// Asserts that two `bool` values are not equal.
    1601
        function assertNotEq(bool left, bool right) external pure;
    1602
    1603
        /// Asserts that two `bool` values are not equal and includes error message into revert string on failure.
    1604
        function assertNotEq(bool left, bool right, string calldata error) external pure;
    1605
    1606
        /// Asserts that two `string` values are not equal.
    1607
        function assertNotEq(string calldata left, string calldata right) external pure;
    1608
    1609
        /// Asserts that two `string` values are not equal and includes error message into revert string on failure.
    1610
        function assertNotEq(string calldata left, string calldata right, string calldata error) external pure;
    1611
    1612
        /// Asserts that two `bytes` values are not equal.
    1613
        function assertNotEq(bytes calldata left, bytes calldata right) external pure;
    1614
    1615
        /// Asserts that two `bytes` values are not equal and includes error message into revert string on failure.
    1616
        function assertNotEq(bytes calldata left, bytes calldata right, string calldata error) external pure;
    1617
    1618
        /// Asserts that two arrays of `bool` values are not equal.
    1619
        function assertNotEq(bool[] calldata left, bool[] calldata right) external pure;
    1620
    1621
        /// Asserts that two arrays of `bool` values are not equal and includes error message into revert string on failure.
    1622
        function assertNotEq(bool[] calldata left, bool[] calldata right, string calldata error) external pure;
    1623
    1624
        /// Asserts that two arrays of `uint256` values are not equal.
    1625
        function assertNotEq(uint256[] calldata left, uint256[] calldata right) external pure;
    1626
    1627
        /// Asserts that two arrays of `uint256` values are not equal and includes error message into revert string on failure.
    1628
        function assertNotEq(uint256[] calldata left, uint256[] calldata right, string calldata error) external pure;
    1629
    1630
        /// Asserts that two arrays of `int256` values are not equal.
    1631
        function assertNotEq(int256[] calldata left, int256[] calldata right) external pure;
    1632
    1633
        /// Asserts that two arrays of `int256` values are not equal and includes error message into revert string on failure.
    1634
        function assertNotEq(int256[] calldata left, int256[] calldata right, string calldata error) external pure;
    1635
    1636
        /// Asserts that two `uint256` values are not equal.
    1637
        function assertNotEq(uint256 left, uint256 right) external pure;
    1638
    1639
        /// Asserts that two arrays of `address` values are not equal.
    1640
        function assertNotEq(address[] calldata left, address[] calldata right) external pure;
    1641
    1642
        /// Asserts that two arrays of `address` values are not equal and includes error message into revert string on failure.
    1643
        function assertNotEq(address[] calldata left, address[] calldata right, string calldata error) external pure;
    1644
    1645
        /// Asserts that two arrays of `bytes32` values are not equal.
    1646
        function assertNotEq(bytes32[] calldata left, bytes32[] calldata right) external pure;
    1647
    1648
        /// Asserts that two arrays of `bytes32` values are not equal and includes error message into revert string on failure.
    1649
        function assertNotEq(bytes32[] calldata left, bytes32[] calldata right, string calldata error) external pure;
    1650
    1651
        /// Asserts that two arrays of `string` values are not equal.
    1652
        function assertNotEq(string[] calldata left, string[] calldata right) external pure;
    1653
    1654
        /// Asserts that two arrays of `string` values are not equal and includes error message into revert string on failure.
    1655
        function assertNotEq(string[] calldata left, string[] calldata right, string calldata error) external pure;
    1656
    1657
        /// Asserts that two arrays of `bytes` values are not equal.
    1658
        function assertNotEq(bytes[] calldata left, bytes[] calldata right) external pure;
    1659
    1660
        /// Asserts that two arrays of `bytes` values are not equal and includes error message into revert string on failure.
    1661
        function assertNotEq(bytes[] calldata left, bytes[] calldata right, string calldata error) external pure;
    1662
    1663
        /// Asserts that two `uint256` values are not equal and includes error message into revert string on failure.
    1664
        function assertNotEq(uint256 left, uint256 right, string calldata error) external pure;
    1665
    1666
        /// Asserts that two `int256` values are not equal.
    1667
        function assertNotEq(int256 left, int256 right) external pure;
    1668
    1669
        /// Asserts that two `int256` values are not equal and includes error message into revert string on failure.
    1670
        function assertNotEq(int256 left, int256 right, string calldata error) external pure;
    1671
    1672
        /// Asserts that two `address` values are not equal.
    1673
        function assertNotEq(address left, address right) external pure;
    1674
    1675
        /// Asserts that two `address` values are not equal and includes error message into revert string on failure.
    1676
        function assertNotEq(address left, address right, string calldata error) external pure;
    1677
    1678
        /// Asserts that two `bytes32` values are not equal.
    1679
        function assertNotEq(bytes32 left, bytes32 right) external pure;
    1680
    1681
        /// Asserts that two `bytes32` values are not equal and includes error message into revert string on failure.
    1682
        function assertNotEq(bytes32 left, bytes32 right, string calldata error) external pure;
    1683
    1684
        /// Asserts that the given condition is true.
    1685
        function assertTrue(bool condition) external pure;
    1686
    1687
        /// Asserts that the given condition is true and includes error message into revert string on failure.
    1688
        function assertTrue(bool condition, string calldata error) external pure;
    1689
    1690
        /// If the condition is false, discard this run's fuzz inputs and generate new ones.
    1691
        function assume(bool condition) external pure;
    1692
    1693
        /// Discard this run's fuzz inputs and generate new ones if next call reverted.
    1694
        function assumeNoRevert() external pure;
    1695
    1696
        /// Discard this run's fuzz inputs and generate new ones if next call reverts with the potential revert parameters.
    1697
        function assumeNoRevert(PotentialRevert calldata potentialRevert) external pure;
    1698
    1699
        /// Discard this run's fuzz inputs and generate new ones if next call reverts with the any of the potential revert parameters.
    1700
        function assumeNoRevert(PotentialRevert[] calldata potentialReverts) external pure;
    1701
    1702
        /// Writes a breakpoint to jump to in the debugger.
    1703
        function breakpoint(string calldata char) external pure;
    1704
    1705
        /// Writes a conditional breakpoint to jump to in the debugger.
    1706
        function breakpoint(string calldata char, bool value) external pure;
    1707
    1708
        /// Returns true if the current Foundry version is greater than or equal to the given version.
    1709
        /// The given version string must be in the format `major.minor.patch`.
    1710
        /// This is equivalent to `foundryVersionCmp(version) >= 0`.
    1711
        function foundryVersionAtLeast(string calldata version) external view returns (bool);
    1712
    1713
        /// Compares the current Foundry version with the given version string.
    1714
        /// The given version string must be in the format `major.minor.patch`.
    1715
        /// Returns:
    1716
        /// -1 if current Foundry version is less than the given version
    1717
        /// 0 if current Foundry version equals the given version
    1718
        /// 1 if current Foundry version is greater than the given version
    1719
        /// This result can then be used with a comparison operator against `0`.
    1720
        /// For example, to check if the current Foundry version is greater than or equal to `1.0.0`:
    1721
        /// `if (foundryVersionCmp("1.0.0") >= 0) { ... }`
    1722
        function foundryVersionCmp(string calldata version) external view returns (int256);
    1723
    1724
        /// Returns a Chain struct for specific alias
    1725
        function getChain(string calldata chainAlias) external view returns (Chain memory chain);
    1726
    1727
        /// Returns a Chain struct for specific chainId
    1728
        function getChain(uint256 chainId) external view returns (Chain memory chain);
    1729
    1730
        /// Returns the Foundry version.
    1731
        /// Format: <cargo_version>-<tag>+<git_sha_short>.<unix_build_timestamp>.<profile>
    1732
        /// Sample output: 0.3.0-nightly+3cb96bde9b.1737036656.debug
    1733
        /// Note: Build timestamps may vary slightly across platforms due to separate CI jobs.
    1734
        /// For reliable version comparisons, use UNIX format (e.g., >= 1700000000)
    1735
        /// to compare timestamps while ignoring minor time differences.
    1736
        function getFoundryVersion() external view returns (string memory version);
    1737
    1738
        /// Returns the RPC url for the given alias.
    1739
        function rpcUrl(string calldata rpcAlias) external view returns (string memory json);
    1740
    1741
        /// Returns all rpc urls and their aliases as structs.
    1742
        function rpcUrlStructs() external view returns (Rpc[] memory urls);
    1743
    1744
        /// Returns all rpc urls and their aliases `[alias, url][]`.
    1745
        function rpcUrls() external view returns (string[2][] memory urls);
    1746
    1747
        /// Suspends execution of the main thread for `duration` milliseconds.
    1748
        function sleep(uint256 duration) external;
    1749
    1750
        // ======== Toml ========
    1751
    1752
        /// Checks if `key` exists in a TOML table.
    1753
        function keyExistsToml(string calldata toml, string calldata key) external view returns (bool);
    1754
    1755
        /// Parses a string of TOML data at `key` and coerces it to `address`.
    1756
        function parseTomlAddress(string calldata toml, string calldata key) external pure returns (address);
    1757
    1758
        /// Parses a string of TOML data at `key` and coerces it to `address[]`.
    1759
        function parseTomlAddressArray(string calldata toml, string calldata key)
    1760
            external
    1761
            pure
    1762
            returns (address[] memory);
    1763
    1764
        /// Parses a string of TOML data at `key` and coerces it to `bool`.
    1765
        function parseTomlBool(string calldata toml, string calldata key) external pure returns (bool);
    1766
    1767
        /// Parses a string of TOML data at `key` and coerces it to `bool[]`.
    1768
        function parseTomlBoolArray(string calldata toml, string calldata key) external pure returns (bool[] memory);
    1769
    1770
        /// Parses a string of TOML data at `key` and coerces it to `bytes`.
    1771
        function parseTomlBytes(string calldata toml, string calldata key) external pure returns (bytes memory);
    1772
    1773
        /// Parses a string of TOML data at `key` and coerces it to `bytes32`.
    1774
        function parseTomlBytes32(string calldata toml, string calldata key) external pure returns (bytes32);
    1775
    1776
        /// Parses a string of TOML data at `key` and coerces it to `bytes32[]`.
    1777
        function parseTomlBytes32Array(string calldata toml, string calldata key)
    1778
            external
    1779
            pure
    1780
            returns (bytes32[] memory);
    1781
    1782
        /// Parses a string of TOML data at `key` and coerces it to `bytes[]`.
    1783
        function parseTomlBytesArray(string calldata toml, string calldata key) external pure returns (bytes[] memory);
    1784
    1785
        /// Parses a string of TOML data at `key` and coerces it to `int256`.
    1786
        function parseTomlInt(string calldata toml, string calldata key) external pure returns (int256);
    1787
    1788
        /// Parses a string of TOML data at `key` and coerces it to `int256[]`.
    1789
        function parseTomlIntArray(string calldata toml, string calldata key) external pure returns (int256[] memory);
    1790
    1791
        /// Returns an array of all the keys in a TOML table.
    1792
        function parseTomlKeys(string calldata toml, string calldata key) external pure returns (string[] memory keys);
    1793
    1794
        /// Parses a string of TOML data at `key` and coerces it to `string`.
    1795
        function parseTomlString(string calldata toml, string calldata key) external pure returns (string memory);
    1796
    1797
        /// Parses a string of TOML data at `key` and coerces it to `string[]`.
    1798
        function parseTomlStringArray(string calldata toml, string calldata key) external pure returns (string[] memory);
    1799
    1800
        /// Parses a string of TOML data at `key` and coerces it to type array corresponding to `typeDescription`.
    1801
        function parseTomlTypeArray(string calldata toml, string calldata key, string calldata typeDescription)
    1802
            external
    1803
            pure
    1804
            returns (bytes memory);
    1805
    1806
        /// Parses a string of TOML data and coerces it to type corresponding to `typeDescription`.
    1807
        function parseTomlType(string calldata toml, string calldata typeDescription)
    1808
            external
    1809
            pure
    1810
            returns (bytes memory);
    1811
    1812
        /// Parses a string of TOML data at `key` and coerces it to type corresponding to `typeDescription`.
    1813
        function parseTomlType(string calldata toml, string calldata key, string calldata typeDescription)
    1814
            external
    1815
            pure
    1816
            returns (bytes memory);
    1817
    1818
        /// Parses a string of TOML data at `key` and coerces it to `uint256`.
    1819
        function parseTomlUint(string calldata toml, string calldata key) external pure returns (uint256);
    1820
    1821
        /// Parses a string of TOML data at `key` and coerces it to `uint256[]`.
    1822
        function parseTomlUintArray(string calldata toml, string calldata key) external pure returns (uint256[] memory);
    1823
    1824
        /// ABI-encodes a TOML table.
    1825
        function parseToml(string calldata toml) external pure returns (bytes memory abiEncodedData);
    1826
    1827
        /// ABI-encodes a TOML table at `key`.
    1828
        function parseToml(string calldata toml, string calldata key) external pure returns (bytes memory abiEncodedData);
    1829
    1830
        /// Takes serialized JSON, converts to TOML and write a serialized TOML to a file.
    1831
        function writeToml(string calldata json, string calldata path) external;
    1832
    1833
        /// Takes serialized JSON, converts to TOML and write a serialized TOML table to an **existing** TOML file, replacing a value with key = <value_key.>
    1834
        /// This is useful to replace a specific value of a TOML file, without having to parse the entire thing.
    1835
        function writeToml(string calldata json, string calldata path, string calldata valueKey) external;
    1836
    1837
        // ======== Utilities ========
    1838
    1839
        /// Compute the address of a contract created with CREATE2 using the given CREATE2 deployer.
    1840
        function computeCreate2Address(bytes32 salt, bytes32 initCodeHash, address deployer)
    1841
            external
    1842
            pure
    1843
            returns (address);
    1844
    1845
        /// Compute the address of a contract created with CREATE2 using the default CREATE2 deployer.
    1846
        function computeCreate2Address(bytes32 salt, bytes32 initCodeHash) external pure returns (address);
    1847
    1848
        /// Compute the address a contract will be deployed at for a given deployer address and nonce.
    1849
        function computeCreateAddress(address deployer, uint256 nonce) external pure returns (address);
    1850
    1851
        /// Utility cheatcode to copy storage of `from` contract to another `to` contract.
    1852
        function copyStorage(address from, address to) external;
    1853
    1854
        /// Returns ENS namehash for provided string.
    1855
        function ensNamehash(string calldata name) external pure returns (bytes32);
    1856
    1857
        /// Gets the label for the specified address.
    1858
        function getLabel(address account) external view returns (string memory currentLabel);
    1859
    1860
        /// Labels an address in call traces.
    1861
        function label(address account, string calldata newLabel) external;
    1862
    1863
        /// Pauses collection of call traces. Useful in cases when you want to skip tracing of
    1864
        /// complex calls which are not useful for debugging.
    1865
        function pauseTracing() external view;
    1866
    1867
        /// Returns a random `address`.
    1868
        function randomAddress() external returns (address);
    1869
    1870
        /// Returns a random `bool`.
    1871
        function randomBool() external view returns (bool);
    1872
    1873
        /// Returns a random byte array value of the given length.
    1874
        function randomBytes(uint256 len) external view returns (bytes memory);
    1875
    1876
        /// Returns a random fixed-size byte array of length 4.
    1877
        function randomBytes4() external view returns (bytes4);
    1878
    1879
        /// Returns a random fixed-size byte array of length 8.
    1880
        function randomBytes8() external view returns (bytes8);
    1881
    1882
        /// Returns a random `int256` value.
    1883
        function randomInt() external view returns (int256);
    1884
    1885
        /// Returns a random `int256` value of given bits.
    1886
        function randomInt(uint256 bits) external view returns (int256);
    1887
    1888
        /// Returns a random uint256 value.
    1889
        function randomUint() external returns (uint256);
    1890
    1891
        /// Returns random uint256 value between the provided range (=min..=max).
    1892
        function randomUint(uint256 min, uint256 max) external returns (uint256);
    1893
    1894
        /// Returns a random `uint256` value of given bits.
    1895
        function randomUint(uint256 bits) external view returns (uint256);
    1896
    1897
        /// Unpauses collection of call traces.
    1898
        function resumeTracing() external view;
    1899
    1900
        /// Utility cheatcode to set arbitrary storage for given target address.
    1901
        function setArbitraryStorage(address target) external;
    1902
    1903
        /// Utility cheatcode to set arbitrary storage for given target address and overwrite
    1904
        /// any storage slots that have been previously set.
    1905
        function setArbitraryStorage(address target, bool overwrite) external;
    1906
    1907
        /// Randomly shuffles an array.
    1908
        function shuffle(uint256[] calldata array) external returns (uint256[] memory);
    1909
    1910
        /// Sorts an array in ascending order.
    1911
        function sort(uint256[] calldata array) external returns (uint256[] memory);
    1912
    1913
        /// Encodes a `bytes` value to a base64url string.
    1914
        function toBase64URL(bytes calldata data) external pure returns (string memory);
    1915
    1916
        /// Encodes a `string` value to a base64url string.
    1917
        function toBase64URL(string calldata data) external pure returns (string memory);
    1918
    1919
        /// Encodes a `bytes` value to a base64 string.
    1920
        function toBase64(bytes calldata data) external pure returns (string memory);
    1921
    1922
        /// Encodes a `string` value to a base64 string.
    1923
        function toBase64(string calldata data) external pure returns (string memory);
    1924
    1925
        // Generates the hash of the canonical EIP-712 type representation.
    1926
        //
    1927
        // Supports 2 different inputs:
    1928
        //  1. Name of the type (i.e. "Transaction"):
    1929
        //     * requires previous binding generation with `forge bind-json`.
    1930
        //     * bindings will be retrieved from the path configured in `foundry.toml`.
    1931
        //
    1932
        //  2. String representation of the type (i.e. "Foo(Bar bar) Bar(uint256 baz)").
    1933
        //     * Note: the cheatcode will output the canonical type even if the input is malformated
    1934
        //             with the wrong order of elements or with extra whitespaces.
    1935
        function eip712HashType(string calldata typeNameOrDefinition) external pure returns (bytes32 typeHash);
    1936
    1937
        // Generates the hash of the canonical EIP-712 type representation.
    1938
        // Requires previous binding generation with `forge bind-json`.
    1939
        //
    1940
        // Params:
    1941
        //  * `bindingsPath`: path where the output of `forge bind-json` is stored.
    1942
        //  * `typeName`: Name of the type (i.e. "Transaction").
    1943
        function eip712HashType(string calldata bindingsPath, string calldata typeName)
    1944
            external
    1945
            pure
    1946
            returns (bytes32 typeHash);
    1947
    1948
        // Generates the struct hash of the canonical EIP-712 type representation and its abi-encoded data.
    1949
        //
    1950
        // Supports 2 different inputs:
    1951
        //  1. Name of the type (i.e. "PermitSingle"):
    1952
        //     * requires previous binding generation with `forge bind-json`.
    1953
        //     * bindings will be retrieved from the path configured in `foundry.toml`.
    1954
        //
    1955
        //  2. String representation of the type (i.e. "Foo(Bar bar) Bar(uint256 baz)").
    1956
        //     * Note: the cheatcode will use the canonical type even if the input is malformated
    1957
        //             with the wrong order of elements or with extra whitespaces.
    1958
        function eip712HashStruct(string calldata typeNameOrDefinition, bytes calldata abiEncodedData)
    1959
            external
    1960
            pure
    1961
            returns (bytes32 typeHash);
    1962
    1963
        // Generates the struct hash of the canonical EIP-712 type representation and its abi-encoded data.
    1964
        // Requires previous binding generation with `forge bind-json`.
    1965
        //
    1966
        // Params:
    1967
        //  * `bindingsPath`: path where the output of `forge bind-json` is stored.
    1968
        //  * `typeName`: Name of the type (i.e. "PermitSingle").
    1969
        //  * `abiEncodedData`: ABI-encoded data for the struct that is being hashed.
    1970
        function eip712HashStruct(string calldata bindingsPath, string calldata typeName, bytes calldata abiEncodedData)
    1971
            external
    1972
            pure
    1973
            returns (bytes32 typeHash);
    1974
    1975
        // Generates a ready-to-sign digest of human-readable typed data following the EIP-712 standard.
    1976
        function eip712HashTypedData(string calldata jsonData) external pure returns (bytes32 digest);
    1977
    }
    1978
    1979
    /// The `Vm` interface does allow manipulation of the EVM state. These are all intended to be used
    1980
    /// in tests, but it is not recommended to use these cheats in scripts.
    1981
    interface Vm is VmSafe {
    1982
        // ======== EVM ========
    1983
    1984
        /// Utility cheatcode to set an EIP-2930 access list for all subsequent transactions.
    1985
        function accessList(AccessListItem[] calldata access) external;
    1986
    1987
        /// Returns the identifier of the currently active fork. Reverts if no fork is currently active.
    1988
        function activeFork() external view returns (uint256 forkId);
    1989
    1990
        /// In forking mode, explicitly grant the given address cheatcode access.
    1991
        function allowCheatcodes(address account) external;
    1992
    1993
        /// Sets `block.blobbasefee`
    1994
        function blobBaseFee(uint256 newBlobBaseFee) external;
    1995
    1996
        /// Sets the blobhashes in the transaction.
    1997
        /// Not available on EVM versions before Cancun.
    1998
        /// If used on unsupported EVM versions it will revert.
    1999
        function blobhashes(bytes32[] calldata hashes) external;
    2000
    2001
        /// Sets `block.chainid`.
    2002
        function chainId(uint256 newChainId) external;
    2003
    2004
        /// Clears all mocked calls.
    2005
        function clearMockedCalls() external;
    2006
    2007
        /// Clones a source account code, state, balance and nonce to a target account and updates in-memory EVM state.
    2008
        function cloneAccount(address source, address target) external;
    2009
    2010
        /// Sets `block.coinbase`.
    2011
        function coinbase(address newCoinbase) external;
    2012
    2013
        /// Marks the slots of an account and the account address as cold.
    2014
        function cool(address target) external;
    2015
    2016
        /// Utility cheatcode to mark specific storage slot as cold, simulating no prior read.
    2017
        function coolSlot(address target, bytes32 slot) external;
    2018
    2019
        /// Creates a new fork with the given endpoint and the _latest_ block and returns the identifier of the fork.
    2020
        function createFork(string calldata urlOrAlias) external returns (uint256 forkId);
    2021
    2022
        /// Creates a new fork with the given endpoint and block and returns the identifier of the fork.
    2023
        function createFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId);
    2024
    2025
        /// Creates a new fork with the given endpoint and at the block the given transaction was mined in,
    2026
        /// replays all transaction mined in the block before the transaction, and returns the identifier of the fork.
    2027
        function createFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId);
    2028
    2029
        /// Creates and also selects a new fork with the given endpoint and the latest block and returns the identifier of the fork.
    2030
        function createSelectFork(string calldata urlOrAlias) external returns (uint256 forkId);
    2031
    2032
        /// Creates and also selects a new fork with the given endpoint and block and returns the identifier of the fork.
    2033
        function createSelectFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId);
    2034
    2035
        /// Creates and also selects new fork with the given endpoint and at the block the given transaction was mined in,
    2036
        /// replays all transaction mined in the block before the transaction, returns the identifier of the fork.
    2037
        function createSelectFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId);
    2038
    2039
        /// Sets an address' balance.
    2040
        function deal(address account, uint256 newBalance) external;
    2041
    2042
        /// Removes the snapshot with the given ID created by `snapshot`.
    2043
        /// Takes the snapshot ID to delete.
    2044
        /// Returns `true` if the snapshot was successfully deleted.
    2045
        /// Returns `false` if the snapshot does not exist.
    2046
        function deleteStateSnapshot(uint256 snapshotId) external returns (bool success);
    2047
    2048
        /// Removes _all_ snapshots previously created by `snapshot`.
    2049
        function deleteStateSnapshots() external;
    2050
    2051
        /// Sets `block.difficulty`.
    2052
        /// Not available on EVM versions from Paris onwards. Use `prevrandao` instead.
    2053
        /// Reverts if used on unsupported EVM versions.
    2054
        function difficulty(uint256 newDifficulty) external;
    2055
    2056
        /// Dump a genesis JSON file's `allocs` to disk.
    2057
        function dumpState(string calldata pathToStateJson) external;
    2058
    2059
        /// Sets an address' code.
    2060
        function etch(address target, bytes calldata newRuntimeBytecode) external;
    2061
    2062
        /// Sets `block.basefee`.
    2063
        function fee(uint256 newBasefee) external;
    2064
    2065
        /// Gets the blockhashes from the current transaction.
    2066
        /// Not available on EVM versions before Cancun.
    2067
        /// If used on unsupported EVM versions it will revert.
    2068
        function getBlobhashes() external view returns (bytes32[] memory hashes);
    2069
    2070
        /// Returns true if the account is marked as persistent.
    2071
        function isPersistent(address account) external view returns (bool persistent);
    2072
    2073
        /// Load a genesis JSON file's `allocs` into the in-memory EVM state.
    2074
        function loadAllocs(string calldata pathToAllocsJson) external;
    2075
    2076
        /// Marks that the account(s) should use persistent storage across fork swaps in a multifork setup
    2077
        /// Meaning, changes made to the state of this account will be kept when switching forks.
    2078
        function makePersistent(address account) external;
    2079
    2080
        /// See `makePersistent(address)`.
    2081
        function makePersistent(address account0, address account1) external;
    2082
    2083
        /// See `makePersistent(address)`.
    2084
        function makePersistent(address account0, address account1, address account2) external;
    2085
    2086
        /// See `makePersistent(address)`.
    2087
        function makePersistent(address[] calldata accounts) external;
    2088
    2089
        /// Reverts a call to an address with specified revert data.
    2090
        function mockCallRevert(address callee, bytes calldata data, bytes calldata revertData) external;
    2091
    2092
        /// Reverts a call to an address with a specific `msg.value`, with specified revert data.
    2093
        function mockCallRevert(address callee, uint256 msgValue, bytes calldata data, bytes calldata revertData)
    2094
            external;
    2095
    2096
        /// Reverts a call to an address with specified revert data.
    2097
        /// Overload to pass the function selector directly `token.approve.selector` instead of `abi.encodeWithSelector(token.approve.selector)`.
    2098
        function mockCallRevert(address callee, bytes4 data, bytes calldata revertData) external;
    2099
    2100
        /// Reverts a call to an address with a specific `msg.value`, with specified revert data.
    2101
        /// Overload to pass the function selector directly `token.approve.selector` instead of `abi.encodeWithSelector(token.approve.selector)`.
    2102
        function mockCallRevert(address callee, uint256 msgValue, bytes4 data, bytes calldata revertData) external;
    2103
    2104
        /// Mocks a call to an address, returning specified data.
    2105
        /// Calldata can either be strict or a partial match, e.g. if you only
    2106
        /// pass a Solidity selector to the expected calldata, then the entire Solidity
    2107
        /// function will be mocked.
    2108
        function mockCall(address callee, bytes calldata data, bytes calldata returnData) external;
    2109
    2110
        /// Mocks a call to an address with a specific `msg.value`, returning specified data.
    2111
        /// Calldata match takes precedence over `msg.value` in case of ambiguity.
    2112
        function mockCall(address callee, uint256 msgValue, bytes calldata data, bytes calldata returnData) external;
    2113
    2114
        /// Mocks a call to an address, returning specified data.
    2115
        /// Calldata can either be strict or a partial match, e.g. if you only
    2116
        /// pass a Solidity selector to the expected calldata, then the entire Solidity
    2117
        /// function will be mocked.
    2118
        /// Overload to pass the function selector directly `token.approve.selector` instead of `abi.encodeWithSelector(token.approve.selector)`.
    2119
        function mockCall(address callee, bytes4 data, bytes calldata returnData) external;
    2120
    2121
        /// Mocks a call to an address with a specific `msg.value`, returning specified data.
    2122
        /// Calldata match takes precedence over `msg.value` in case of ambiguity.
    2123
        /// Overload to pass the function selector directly `token.approve.selector` instead of `abi.encodeWithSelector(token.approve.selector)`.
    2124
        function mockCall(address callee, uint256 msgValue, bytes4 data, bytes calldata returnData) external;
    2125
    2126
        /// Mocks multiple calls to an address, returning specified data for each call.
    2127
        function mockCalls(address callee, bytes calldata data, bytes[] calldata returnData) external;
    2128
    2129
        /// Mocks multiple calls to an address with a specific `msg.value`, returning specified data for each call.
    2130
        function mockCalls(address callee, uint256 msgValue, bytes calldata data, bytes[] calldata returnData) external;
    2131
    2132
        /// Whenever a call is made to `callee` with calldata `data`, this cheatcode instead calls
    2133
        /// `target` with the same calldata. This functionality is similar to a delegate call made to
    2134
        /// `target` contract from `callee`.
    2135
        /// Can be used to substitute a call to a function with another implementation that captures
    2136
        /// the primary logic of the original function but is easier to reason about.
    2137
        /// If calldata is not a strict match then partial match by selector is attempted.
    2138
        function mockFunction(address callee, address target, bytes calldata data) external;
    2139
    2140
        /// Utility cheatcode to remove any EIP-2930 access list set by `accessList` cheatcode.
    2141
        function noAccessList() external;
    2142
    2143
        /// Sets the *next* call's `msg.sender` to be the input address.
    2144
        function prank(address msgSender) external;
    2145
    2146
        /// Sets the *next* call's `msg.sender` to be the input address, and the `tx.origin` to be the second input.
    2147
        function prank(address msgSender, address txOrigin) external;
    2148
    2149
        /// Sets the *next* delegate call's `msg.sender` to be the input address.
    2150
        function prank(address msgSender, bool delegateCall) external;
    2151
    2152
        /// Sets the *next* delegate call's `msg.sender` to be the input address, and the `tx.origin` to be the second input.
    2153
        function prank(address msgSender, address txOrigin, bool delegateCall) external;
    2154
    2155
        /// Sets `block.prevrandao`.
    2156
        /// Not available on EVM versions before Paris. Use `difficulty` instead.
    2157
        /// If used on unsupported EVM versions it will revert.
    2158
        function prevrandao(bytes32 newPrevrandao) external;
    2159
    2160
        /// Sets `block.prevrandao`.
    2161
        /// Not available on EVM versions before Paris. Use `difficulty` instead.
    2162
        /// If used on unsupported EVM versions it will revert.
    2163
        function prevrandao(uint256 newPrevrandao) external;
    2164
    2165
        /// Reads the current `msg.sender` and `tx.origin` from state and reports if there is any active caller modification.
    2166
        function readCallers() external returns (CallerMode callerMode, address msgSender, address txOrigin);
    2167
    2168
        /// Resets the nonce of an account to 0 for EOAs and 1 for contract accounts.
    2169
        function resetNonce(address account) external;
    2170
    2171
        /// Revert the state of the EVM to a previous snapshot
    2172
        /// Takes the snapshot ID to revert to.
    2173
        /// Returns `true` if the snapshot was successfully reverted.
    2174
        /// Returns `false` if the snapshot does not exist.
    2175
        /// **Note:** This does not automatically delete the snapshot. To delete the snapshot use `deleteStateSnapshot`.
    2176
        function revertToState(uint256 snapshotId) external returns (bool success);
    2177
    2178
        /// Revert the state of the EVM to a previous snapshot and automatically deletes the snapshots
    2179
        /// Takes the snapshot ID to revert to.
    2180
        /// Returns `true` if the snapshot was successfully reverted and deleted.
    2181
        /// Returns `false` if the snapshot does not exist.
    2182
        function revertToStateAndDelete(uint256 snapshotId) external returns (bool success);
    2183
    2184
        /// Revokes persistent status from the address, previously added via `makePersistent`.
    2185
        function revokePersistent(address account) external;
    2186
    2187
        /// See `revokePersistent(address)`.
    2188
        function revokePersistent(address[] calldata accounts) external;
    2189
    2190
        /// Sets `block.height`.
    2191
        function roll(uint256 newHeight) external;
    2192
    2193
        /// Updates the currently active fork to given block number
    2194
        /// This is similar to `roll` but for the currently active fork.
    2195
        function rollFork(uint256 blockNumber) external;
    2196
    2197
        /// Updates the currently active fork to given transaction. This will `rollFork` with the number
    2198
        /// of the block the transaction was mined in and replays all transaction mined before it in the block.
    2199
        function rollFork(bytes32 txHash) external;
    2200
    2201
        /// Updates the given fork to given block number.
    2202
        function rollFork(uint256 forkId, uint256 blockNumber) external;
    2203
    2204
        /// Updates the given fork to block number of the given transaction and replays all transaction mined before it in the block.
    2205
        function rollFork(uint256 forkId, bytes32 txHash) external;
    2206
    2207
        /// Takes a fork identifier created by `createFork` and sets the corresponding forked state as active.
    2208
        function selectFork(uint256 forkId) external;
    2209
    2210
        /// Set blockhash for the current block.
    2211
        /// It only sets the blockhash for blocks where `block.number - 256 <= number < block.number`.
    2212
        function setBlockhash(uint256 blockNumber, bytes32 blockHash) external;
    2213
    2214
        /// Sets the nonce of an account. Must be higher than the current nonce of the account.
    2215
        function setNonce(address account, uint64 newNonce) external;
    2216
    2217
        /// Sets the nonce of an account to an arbitrary value.
    2218
        function setNonceUnsafe(address account, uint64 newNonce) external;
    2219
    2220
        /// Snapshot capture the gas usage of the last call by name from the callee perspective.
    2221
        function snapshotGasLastCall(string calldata name) external returns (uint256 gasUsed);
    2222
    2223
        /// Snapshot capture the gas usage of the last call by name in a group from the callee perspective.
    2224
        function snapshotGasLastCall(string calldata group, string calldata name) external returns (uint256 gasUsed);
    2225
    2226
        /// Snapshot the current state of the evm.
    2227
        /// Returns the ID of the snapshot that was created.
    2228
        /// To revert a snapshot use `revertToState`.
    2229
        function snapshotState() external returns (uint256 snapshotId);
    2230
    2231
        /// Snapshot capture an arbitrary numerical value by name.
    2232
        /// The group name is derived from the contract name.
    2233
        function snapshotValue(string calldata name, uint256 value) external;
    2234
    2235
        /// Snapshot capture an arbitrary numerical value by name in a group.
    2236
        function snapshotValue(string calldata group, string calldata name, uint256 value) external;
    2237
    2238
        /// Sets all subsequent calls' `msg.sender` to be the input address until `stopPrank` is called.
    2239
        function startPrank(address msgSender) external;
    2240
    2241
        /// Sets all subsequent calls' `msg.sender` to be the input address until `stopPrank` is called, and the `tx.origin` to be the second input.
    2242
        function startPrank(address msgSender, address txOrigin) external;
    2243
    2244
        /// Sets all subsequent delegate calls' `msg.sender` to be the input address until `stopPrank` is called.
    2245
        function startPrank(address msgSender, bool delegateCall) external;
    2246
    2247
        /// Sets all subsequent delegate calls' `msg.sender` to be the input address until `stopPrank` is called, and the `tx.origin` to be the second input.
    2248
        function startPrank(address msgSender, address txOrigin, bool delegateCall) external;
    2249
    2250
        /// Start a snapshot capture of the current gas usage by name.
    2251
        /// The group name is derived from the contract name.
    2252
        function startSnapshotGas(string calldata name) external;
    2253
    2254
        /// Start a snapshot capture of the current gas usage by name in a group.
    2255
        function startSnapshotGas(string calldata group, string calldata name) external;
    2256
    2257
        /// Resets subsequent calls' `msg.sender` to be `address(this)`.
    2258
        function stopPrank() external;
    2259
    2260
        /// Stop the snapshot capture of the current gas by latest snapshot name, capturing the gas used since the start.
    2261
        function stopSnapshotGas() external returns (uint256 gasUsed);
    2262
    2263
        /// Stop the snapshot capture of the current gas usage by name, capturing the gas used since the start.
    2264
        /// The group name is derived from the contract name.
    2265
        function stopSnapshotGas(string calldata name) external returns (uint256 gasUsed);
    2266
    2267
        /// Stop the snapshot capture of the current gas usage by name in a group, capturing the gas used since the start.
    2268
        function stopSnapshotGas(string calldata group, string calldata name) external returns (uint256 gasUsed);
    2269
    2270
        /// Stores a value to an address' storage slot.
    2271
        function store(address target, bytes32 slot, bytes32 value) external;
    2272
    2273
        /// Fetches the given transaction from the active fork and executes it on the current state.
    2274
        function transact(bytes32 txHash) external;
    2275
    2276
        /// Fetches the given transaction from the given fork and executes it on the current state.
    2277
        function transact(uint256 forkId, bytes32 txHash) external;
    2278
    2279
        /// Sets `tx.gasprice`.
    2280
        function txGasPrice(uint256 newGasPrice) external;
    2281
    2282
        /// Utility cheatcode to mark specific storage slot as warm, simulating a prior read.
    2283
        function warmSlot(address target, bytes32 slot) external;
    2284
    2285
        /// Sets `block.timestamp`.
    2286
        function warp(uint256 newTimestamp) external;
    2287
    2288
        /// `deleteSnapshot` is being deprecated in favor of `deleteStateSnapshot`. It will be removed in future versions.
    2289
        function deleteSnapshot(uint256 snapshotId) external returns (bool success);
    2290
    2291
        /// `deleteSnapshots` is being deprecated in favor of `deleteStateSnapshots`. It will be removed in future versions.
    2292
        function deleteSnapshots() external;
    2293
    2294
        /// `revertToAndDelete` is being deprecated in favor of `revertToStateAndDelete`. It will be removed in future versions.
    2295
        function revertToAndDelete(uint256 snapshotId) external returns (bool success);
    2296
    2297
        /// `revertTo` is being deprecated in favor of `revertToState`. It will be removed in future versions.
    2298
        function revertTo(uint256 snapshotId) external returns (bool success);
    2299
    2300
        /// `snapshot` is being deprecated in favor of `snapshotState`. It will be removed in future versions.
    2301
        function snapshot() external returns (uint256 snapshotId);
    2302
    2303
        // ======== Testing ========
    2304
    2305
        /// Expect a call to an address with the specified `msg.value` and calldata, and a *minimum* amount of gas.
    2306
        function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data) external;
    2307
    2308
        /// Expect given number of calls to an address with the specified `msg.value` and calldata, and a *minimum* amount of gas.
    2309
        function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data, uint64 count)
    2310
            external;
    2311
    2312
        /// Expects a call to an address with the specified calldata.
    2313
        /// Calldata can either be a strict or a partial match.
    2314
        function expectCall(address callee, bytes calldata data) external;
    2315
    2316
        /// Expects given number of calls to an address with the specified calldata.
    2317
        function expectCall(address callee, bytes calldata data, uint64 count) external;
    2318
    2319
        /// Expects a call to an address with the specified `msg.value` and calldata.
    2320
        function expectCall(address callee, uint256 msgValue, bytes calldata data) external;
    2321
    2322
        /// Expects given number of calls to an address with the specified `msg.value` and calldata.
    2323
        function expectCall(address callee, uint256 msgValue, bytes calldata data, uint64 count) external;
    2324
    2325
        /// Expect a call to an address with the specified `msg.value`, gas, and calldata.
    2326
        function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data) external;
    2327
    2328
        /// Expects given number of calls to an address with the specified `msg.value`, gas, and calldata.
    2329
        function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data, uint64 count) external;
    2330
    2331
        /// Expects the deployment of the specified bytecode by the specified address using the CREATE opcode
    2332
        function expectCreate(bytes calldata bytecode, address deployer) external;
    2333
    2334
        /// Expects the deployment of the specified bytecode by the specified address using the CREATE2 opcode
    2335
        function expectCreate2(bytes calldata bytecode, address deployer) external;
    2336
    2337
        /// Prepare an expected anonymous log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData.).
    2338
        /// Call this function, then emit an anonymous event, then call a function. Internally after the call, we check if
    2339
        /// logs were emitted in the expected order with the expected topics and data (as specified by the booleans).
    2340
        function expectEmitAnonymous(bool checkTopic0, bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData)
    2341
            external;
    2342
    2343
        /// Same as the previous method, but also checks supplied address against emitting contract.
    2344
        function expectEmitAnonymous(
    2345
            bool checkTopic0,
    2346
            bool checkTopic1,
    2347
            bool checkTopic2,
    2348
            bool checkTopic3,
    2349
            bool checkData,
    2350
            address emitter
    2351
        ) external;
    2352
    2353
        /// Prepare an expected anonymous log with all topic and data checks enabled.
    2354
        /// Call this function, then emit an anonymous event, then call a function. Internally after the call, we check if
    2355
        /// logs were emitted in the expected order with the expected topics and data.
    2356
        function expectEmitAnonymous() external;
    2357
    2358
        /// Same as the previous method, but also checks supplied address against emitting contract.
    2359
        function expectEmitAnonymous(address emitter) external;
    2360
    2361
        /// Prepare an expected log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData.).
    2362
        /// Call this function, then emit an event, then call a function. Internally after the call, we check if
    2363
        /// logs were emitted in the expected order with the expected topics and data (as specified by the booleans).
    2364
        function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData) external;
    2365
    2366
        /// Same as the previous method, but also checks supplied address against emitting contract.
    2367
        function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData, address emitter)
    2368
            external;
    2369
    2370
        /// Prepare an expected log with all topic and data checks enabled.
    2371
        /// Call this function, then emit an event, then call a function. Internally after the call, we check if
    2372
        /// logs were emitted in the expected order with the expected topics and data.
    2373
        function expectEmit() external;
    2374
    2375
        /// Same as the previous method, but also checks supplied address against emitting contract.
    2376
        function expectEmit(address emitter) external;
    2377
    2378
        /// Expect a given number of logs with the provided topics.
    2379
        function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData, uint64 count) external;
    2380
    2381
        /// Expect a given number of logs from a specific emitter with the provided topics.
    2382
        function expectEmit(
    2383
            bool checkTopic1,
    2384
            bool checkTopic2,
    2385
            bool checkTopic3,
    2386
            bool checkData,
    2387
            address emitter,
    2388
            uint64 count
    2389
        ) external;
    2390
    2391
        /// Expect a given number of logs with all topic and data checks enabled.
    2392
        function expectEmit(uint64 count) external;
    2393
    2394
        /// Expect a given number of logs from a specific emitter with all topic and data checks enabled.
    2395
        function expectEmit(address emitter, uint64 count) external;
    2396
    2397
        /// Expects an error on next call that starts with the revert data.
    2398
        function expectPartialRevert(bytes4 revertData) external;
    2399
    2400
        /// Expects an error on next call to reverter address, that starts with the revert data.
    2401
        function expectPartialRevert(bytes4 revertData, address reverter) external;
    2402
    2403
        /// Expects an error on next call with any revert data.
    2404
        function expectRevert() external;
    2405
    2406
        /// Expects an error on next call that exactly matches the revert data.
    2407
        function expectRevert(bytes4 revertData) external;
    2408
    2409
        /// Expects a `count` number of reverts from the upcoming calls from the reverter address that match the revert data.
    2410
        function expectRevert(bytes4 revertData, address reverter, uint64 count) external;
    2411
    2412
        /// Expects a `count` number of reverts from the upcoming calls from the reverter address that exactly match the revert data.
    2413
        function expectRevert(bytes calldata revertData, address reverter, uint64 count) external;
    2414
    2415
        /// Expects an error on next call that exactly matches the revert data.
    2416
        function expectRevert(bytes calldata revertData) external;
    2417
    2418
        /// Expects an error with any revert data on next call to reverter address.
    2419
        function expectRevert(address reverter) external;
    2420
    2421
        /// Expects an error from reverter address on next call, with any revert data.
    2422
        function expectRevert(bytes4 revertData, address reverter) external;
    2423
    2424
        /// Expects an error from reverter address on next call, that exactly matches the revert data.
    2425
        function expectRevert(bytes calldata revertData, address reverter) external;
    2426
    2427
        /// Expects a `count` number of reverts from the upcoming calls with any revert data or reverter.
    2428
        function expectRevert(uint64 count) external;
    2429
    2430
        /// Expects a `count` number of reverts from the upcoming calls that match the revert data.
    2431
        function expectRevert(bytes4 revertData, uint64 count) external;
    2432
    2433
        /// Expects a `count` number of reverts from the upcoming calls that exactly match the revert data.
    2434
        function expectRevert(bytes calldata revertData, uint64 count) external;
    2435
    2436
        /// Expects a `count` number of reverts from the upcoming calls from the reverter address.
    2437
        function expectRevert(address reverter, uint64 count) external;
    2438
    2439
        /// Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the current subcontext. If any other
    2440
        /// memory is written to, the test will fail. Can be called multiple times to add more ranges to the set.
    2441
        function expectSafeMemory(uint64 min, uint64 max) external;
    2442
    2443
        /// Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the next created subcontext.
    2444
        /// If any other memory is written to, the test will fail. Can be called multiple times to add more ranges
    2445
        /// to the set.
    2446
        function expectSafeMemoryCall(uint64 min, uint64 max) external;
    2447
    2448
        /// Marks a test as skipped. Must be called at the top level of a test.
    2449
        function skip(bool skipTest) external;
    2450
    2451
        /// Marks a test as skipped with a reason. Must be called at the top level of a test.
    2452
        function skip(bool skipTest, string calldata reason) external;
    2453
    2454
        /// Stops all safe memory expectation in the current subcontext.
    2455
        function stopExpectSafeMemory() external;
    2456
    2457
        // ======== Utilities ========
    2458
    2459
        /// Causes the next contract creation (via new) to fail and return its initcode in the returndata buffer.
    2460
        /// This allows type-safe access to the initcode payload that would be used for contract creation.
    2461
        /// Example usage:
    2462
        /// vm.interceptInitcode();
    2463
        /// bytes memory initcode;
    2464
        /// try new MyContract(param1, param2) { assert(false); }
    2465
        /// catch (bytes memory interceptedInitcode) { initcode = interceptedInitcode; }
    2466
        function interceptInitcode() external;
    2467
    }
    2468
    5.0% lib/forge-std/src/console.sol
    Lines covered: 1 / 19 (5.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    pragma solidity >=0.4.22 <0.9.0;
    3
    4
    library console {
    5
        address constant CONSOLE_ADDRESS =
    6
            0x000000000000000000636F6e736F6c652e6c6f67;
    7
    8
        function _sendLogPayloadImplementation(bytes memory payload) internal view {
    9
            address consoleAddress = CONSOLE_ADDRESS;
    10
            /// @solidity memory-safe-assembly
    11
            assembly {
    12
                pop(
    13
                    staticcall(
    14
                        gas(),
    15
                        consoleAddress,
    16
                        add(payload, 32),
    17
                        mload(payload),
    18
                        0,
    19
                        0
    20
                    )
    21
                )
    22
            }
    23
        }
    24
    25
        function _castToPure(
    26
          function(bytes memory) internal view fnIn
    27
        ) internal pure returns (function(bytes memory) pure fnOut) {
    28
            assembly {
    29
                fnOut := fnIn
    30
            }
    31
        }
    32
    33
        function _sendLogPayload(bytes memory payload) internal pure {
    34
            _castToPure(_sendLogPayloadImplementation)(payload);
    35
        }
    36
    37
        function log() internal pure {
    38
            _sendLogPayload(abi.encodeWithSignature("log()"));
    39
        }
    40
    41
        function logInt(int256 p0) internal pure {
    42
            _sendLogPayload(abi.encodeWithSignature("log(int256)", p0));
    43
        }
    44
    45
        function logUint(uint256 p0) internal pure {
    46
            _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0));
    47
        }
    48
    49
        function logString(string memory p0) internal pure {
    50
            _sendLogPayload(abi.encodeWithSignature("log(string)", p0));
    51
        }
    52
    53
        function logBool(bool p0) internal pure {
    54
            _sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
    55
        }
    56
    57
        function logAddress(address p0) internal pure {
    58
            _sendLogPayload(abi.encodeWithSignature("log(address)", p0));
    59
        }
    60
    61
        function logBytes(bytes memory p0) internal pure {
    62
            _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0));
    63
        }
    64
    65
        function logBytes1(bytes1 p0) internal pure {
    66
            _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0));
    67
        }
    68
    69
        function logBytes2(bytes2 p0) internal pure {
    70
            _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0));
    71
        }
    72
    73
        function logBytes3(bytes3 p0) internal pure {
    74
            _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0));
    75
        }
    76
    77
        function logBytes4(bytes4 p0) internal pure {
    78
            _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0));
    79
        }
    80
    81
        function logBytes5(bytes5 p0) internal pure {
    82
            _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0));
    83
        }
    84
    85
        function logBytes6(bytes6 p0) internal pure {
    86
            _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0));
    87
        }
    88
    89
        function logBytes7(bytes7 p0) internal pure {
    90
            _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0));
    91
        }
    92
    93
        function logBytes8(bytes8 p0) internal pure {
    94
            _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0));
    95
        }
    96
    97
        function logBytes9(bytes9 p0) internal pure {
    98
            _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0));
    99
        }
    100
    101
        function logBytes10(bytes10 p0) internal pure {
    102
            _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0));
    103
        }
    104
    105
        function logBytes11(bytes11 p0) internal pure {
    106
            _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0));
    107
        }
    108
    109
        function logBytes12(bytes12 p0) internal pure {
    110
            _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0));
    111
        }
    112
    113
        function logBytes13(bytes13 p0) internal pure {
    114
            _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0));
    115
        }
    116
    117
        function logBytes14(bytes14 p0) internal pure {
    118
            _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0));
    119
        }
    120
    121
        function logBytes15(bytes15 p0) internal pure {
    122
            _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0));
    123
        }
    124
    125
        function logBytes16(bytes16 p0) internal pure {
    126
            _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0));
    127
        }
    128
    129
        function logBytes17(bytes17 p0) internal pure {
    130
            _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0));
    131
        }
    132
    133
        function logBytes18(bytes18 p0) internal pure {
    134
            _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0));
    135
        }
    136
    137
        function logBytes19(bytes19 p0) internal pure {
    138
            _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0));
    139
        }
    140
    141
        function logBytes20(bytes20 p0) internal pure {
    142
            _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0));
    143
        }
    144
    145
        function logBytes21(bytes21 p0) internal pure {
    146
            _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0));
    147
        }
    148
    149
        function logBytes22(bytes22 p0) internal pure {
    150
            _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0));
    151
        }
    152
    153
        function logBytes23(bytes23 p0) internal pure {
    154
            _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0));
    155
        }
    156
    157
        function logBytes24(bytes24 p0) internal pure {
    158
            _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0));
    159
        }
    160
    161
        function logBytes25(bytes25 p0) internal pure {
    162
            _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0));
    163
        }
    164
    165
        function logBytes26(bytes26 p0) internal pure {
    166
            _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0));
    167
        }
    168
    169
        function logBytes27(bytes27 p0) internal pure {
    170
            _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0));
    171
        }
    172
    173
        function logBytes28(bytes28 p0) internal pure {
    174
            _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0));
    175
        }
    176
    177
        function logBytes29(bytes29 p0) internal pure {
    178
            _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0));
    179
        }
    180
    181
        function logBytes30(bytes30 p0) internal pure {
    182
            _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0));
    183
        }
    184
    185
        function logBytes31(bytes31 p0) internal pure {
    186
            _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0));
    187
        }
    188
    189
        function logBytes32(bytes32 p0) internal pure {
    190
            _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0));
    191
        }
    192
    193
        function log(uint256 p0) internal pure {
    194
            _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0));
    195
        }
    196
    197
        function log(int256 p0) internal pure {
    198
            _sendLogPayload(abi.encodeWithSignature("log(int256)", p0));
    199
        }
    200
    201
        function log(string memory p0) internal pure {
    202
            _sendLogPayload(abi.encodeWithSignature("log(string)", p0));
    203
        }
    204
    205
        function log(bool p0) internal pure {
    206
            _sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
    207
        }
    208
    209
        function log(address p0) internal pure {
    210
            _sendLogPayload(abi.encodeWithSignature("log(address)", p0));
    211
        }
    212
    213
        function log(uint256 p0, uint256 p1) internal pure {
    214
            _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256)", p0, p1));
    215
        }
    216
    217
        function log(uint256 p0, string memory p1) internal pure {
    218
            _sendLogPayload(abi.encodeWithSignature("log(uint256,string)", p0, p1));
    219
        }
    220
    221
        function log(uint256 p0, bool p1) internal pure {
    222
            _sendLogPayload(abi.encodeWithSignature("log(uint256,bool)", p0, p1));
    223
        }
    224
    225
        function log(uint256 p0, address p1) internal pure {
    226
            _sendLogPayload(abi.encodeWithSignature("log(uint256,address)", p0, p1));
    227
        }
    228
    229
        function log(string memory p0, uint256 p1) internal pure {
    230
            _sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1));
    231
        }
    232
    233
        function log(string memory p0, int256 p1) internal pure {
    234
            _sendLogPayload(abi.encodeWithSignature("log(string,int256)", p0, p1));
    235
        }
    236
    237
        function log(string memory p0, string memory p1) internal pure {
    238
            _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1));
    239
        }
    240
    241
        function log(string memory p0, bool p1) internal pure {
    242
            _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1));
    243
        }
    244
    245
        function log(string memory p0, address p1) internal pure {
    246
            _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1));
    247
        }
    248
    249
        function log(bool p0, uint256 p1) internal pure {
    250
            _sendLogPayload(abi.encodeWithSignature("log(bool,uint256)", p0, p1));
    251
        }
    252
    253
        function log(bool p0, string memory p1) internal pure {
    254
            _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1));
    255
        }
    256
    257
        function log(bool p0, bool p1) internal pure {
    258
            _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1));
    259
        }
    260
    261
        function log(bool p0, address p1) internal pure {
    262
            _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1));
    263
        }
    264
    265
        function log(address p0, uint256 p1) internal pure {
    266
            _sendLogPayload(abi.encodeWithSignature("log(address,uint256)", p0, p1));
    267
        }
    268
    269
        function log(address p0, string memory p1) internal pure {
    270
            _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1));
    271
        }
    272
    273
        function log(address p0, bool p1) internal pure {
    274
            _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1));
    275
        }
    276
    277
        function log(address p0, address p1) internal pure {
    278
            _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1));
    279
        }
    280
    281
        function log(uint256 p0, uint256 p1, uint256 p2) internal pure {
    282
            _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256)", p0, p1, p2));
    283
        }
    284
    285
        function log(uint256 p0, uint256 p1, string memory p2) internal pure {
    286
            _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string)", p0, p1, p2));
    287
        }
    288
    289
        function log(uint256 p0, uint256 p1, bool p2) internal pure {
    290
            _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool)", p0, p1, p2));
    291
        }
    292
    293
        function log(uint256 p0, uint256 p1, address p2) internal pure {
    294
            _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address)", p0, p1, p2));
    295
        }
    296
    297
        function log(uint256 p0, string memory p1, uint256 p2) internal pure {
    298
            _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256)", p0, p1, p2));
    299
        }
    300
    301
        function log(uint256 p0, string memory p1, string memory p2) internal pure {
    302
            _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string)", p0, p1, p2));
    303
        }
    304
    305
        function log(uint256 p0, string memory p1, bool p2) internal pure {
    306
            _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool)", p0, p1, p2));
    307
        }
    308
    309
        function log(uint256 p0, string memory p1, address p2) internal pure {
    310
            _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address)", p0, p1, p2));
    311
        }
    312
    313
        function log(uint256 p0, bool p1, uint256 p2) internal pure {
    314
            _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256)", p0, p1, p2));
    315
        }
    316
    317
        function log(uint256 p0, bool p1, string memory p2) internal pure {
    318
            _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string)", p0, p1, p2));
    319
        }
    320
    321
        function log(uint256 p0, bool p1, bool p2) internal pure {
    322
            _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool)", p0, p1, p2));
    323
        }
    324
    325
        function log(uint256 p0, bool p1, address p2) internal pure {
    326
            _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address)", p0, p1, p2));
    327
        }
    328
    329
        function log(uint256 p0, address p1, uint256 p2) internal pure {
    330
            _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256)", p0, p1, p2));
    331
        }
    332
    333
        function log(uint256 p0, address p1, string memory p2) internal pure {
    334
            _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string)", p0, p1, p2));
    335
        }
    336
    337
        function log(uint256 p0, address p1, bool p2) internal pure {
    338
            _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool)", p0, p1, p2));
    339
        }
    340
    341
        function log(uint256 p0, address p1, address p2) internal pure {
    342
            _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address)", p0, p1, p2));
    343
        }
    344
    345
        function log(string memory p0, uint256 p1, uint256 p2) internal pure {
    346
            _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256)", p0, p1, p2));
    347
        }
    348
    349
        function log(string memory p0, uint256 p1, string memory p2) internal pure {
    350
            _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string)", p0, p1, p2));
    351
        }
    352
    353
        function log(string memory p0, uint256 p1, bool p2) internal pure {
    354
            _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool)", p0, p1, p2));
    355
        }
    356
    357
        function log(string memory p0, uint256 p1, address p2) internal pure {
    358
            _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address)", p0, p1, p2));
    359
        }
    360
    361
        function log(string memory p0, string memory p1, uint256 p2) internal pure {
    362
            _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256)", p0, p1, p2));
    363
        }
    364
    365
        function log(string memory p0, string memory p1, string memory p2) internal pure {
    366
            _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2));
    367
        }
    368
    369
        function log(string memory p0, string memory p1, bool p2) internal pure {
    370
            _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2));
    371
        }
    372
    373
        function log(string memory p0, string memory p1, address p2) internal pure {
    374
            _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2));
    375
        }
    376
    377
        function log(string memory p0, bool p1, uint256 p2) internal pure {
    378
            _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256)", p0, p1, p2));
    379
        }
    380
    381
        function log(string memory p0, bool p1, string memory p2) internal pure {
    382
            _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2));
    383
        }
    384
    385
        function log(string memory p0, bool p1, bool p2) internal pure {
    386
            _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2));
    387
        }
    388
    389
        function log(string memory p0, bool p1, address p2) internal pure {
    390
            _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2));
    391
        }
    392
    393
        function log(string memory p0, address p1, uint256 p2) internal pure {
    394
            _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256)", p0, p1, p2));
    395
        }
    396
    397
        function log(string memory p0, address p1, string memory p2) internal pure {
    398
            _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2));
    399
        }
    400
    401
        function log(string memory p0, address p1, bool p2) internal pure {
    402
            _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2));
    403
        }
    404
    405
        function log(string memory p0, address p1, address p2) internal pure {
    406
            _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2));
    407
        }
    408
    409
        function log(bool p0, uint256 p1, uint256 p2) internal pure {
    410
            _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256)", p0, p1, p2));
    411
        }
    412
    413
        function log(bool p0, uint256 p1, string memory p2) internal pure {
    414
            _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string)", p0, p1, p2));
    415
        }
    416
    417
        function log(bool p0, uint256 p1, bool p2) internal pure {
    418
            _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool)", p0, p1, p2));
    419
        }
    420
    421
        function log(bool p0, uint256 p1, address p2) internal pure {
    422
            _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address)", p0, p1, p2));
    423
        }
    424
    425
        function log(bool p0, string memory p1, uint256 p2) internal pure {
    426
            _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256)", p0, p1, p2));
    427
        }
    428
    429
        function log(bool p0, string memory p1, string memory p2) internal pure {
    430
            _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2));
    431
        }
    432
    433
        function log(bool p0, string memory p1, bool p2) internal pure {
    434
            _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2));
    435
        }
    436
    437
        function log(bool p0, string memory p1, address p2) internal pure {
    438
            _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2));
    439
        }
    440
    441
        function log(bool p0, bool p1, uint256 p2) internal pure {
    442
            _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256)", p0, p1, p2));
    443
        }
    444
    445
        function log(bool p0, bool p1, string memory p2) internal pure {
    446
            _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2));
    447
        }
    448
    449
        function log(bool p0, bool p1, bool p2) internal pure {
    450
            _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2));
    451
        }
    452
    453
        function log(bool p0, bool p1, address p2) internal pure {
    454
            _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2));
    455
        }
    456
    457
        function log(bool p0, address p1, uint256 p2) internal pure {
    458
            _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256)", p0, p1, p2));
    459
        }
    460
    461
        function log(bool p0, address p1, string memory p2) internal pure {
    462
            _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2));
    463
        }
    464
    465
        function log(bool p0, address p1, bool p2) internal pure {
    466
            _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2));
    467
        }
    468
    469
        function log(bool p0, address p1, address p2) internal pure {
    470
            _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2));
    471
        }
    472
    473
        function log(address p0, uint256 p1, uint256 p2) internal pure {
    474
            _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256)", p0, p1, p2));
    475
        }
    476
    477
        function log(address p0, uint256 p1, string memory p2) internal pure {
    478
            _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string)", p0, p1, p2));
    479
        }
    480
    481
        function log(address p0, uint256 p1, bool p2) internal pure {
    482
            _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool)", p0, p1, p2));
    483
        }
    484
    485
        function log(address p0, uint256 p1, address p2) internal pure {
    486
            _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address)", p0, p1, p2));
    487
        }
    488
    489
        function log(address p0, string memory p1, uint256 p2) internal pure {
    490
            _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256)", p0, p1, p2));
    491
        }
    492
    493
        function log(address p0, string memory p1, string memory p2) internal pure {
    494
            _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2));
    495
        }
    496
    497
        function log(address p0, string memory p1, bool p2) internal pure {
    498
            _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2));
    499
        }
    500
    501
        function log(address p0, string memory p1, address p2) internal pure {
    502
            _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2));
    503
        }
    504
    505
        function log(address p0, bool p1, uint256 p2) internal pure {
    506
            _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256)", p0, p1, p2));
    507
        }
    508
    509
        function log(address p0, bool p1, string memory p2) internal pure {
    510
            _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2));
    511
        }
    512
    513
        function log(address p0, bool p1, bool p2) internal pure {
    514
            _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2));
    515
        }
    516
    517
        function log(address p0, bool p1, address p2) internal pure {
    518
            _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2));
    519
        }
    520
    521
        function log(address p0, address p1, uint256 p2) internal pure {
    522
            _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256)", p0, p1, p2));
    523
        }
    524
    525
        function log(address p0, address p1, string memory p2) internal pure {
    526
            _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2));
    527
        }
    528
    529
        function log(address p0, address p1, bool p2) internal pure {
    530
            _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2));
    531
        }
    532
    533
        function log(address p0, address p1, address p2) internal pure {
    534
            _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2));
    535
        }
    536
    537
        function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
    538
            _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,uint256)", p0, p1, p2, p3));
    539
        }
    540
    541
        function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal pure {
    542
            _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,string)", p0, p1, p2, p3));
    543
        }
    544
    545
        function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure {
    546
            _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,bool)", p0, p1, p2, p3));
    547
        }
    548
    549
        function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure {
    550
            _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,address)", p0, p1, p2, p3));
    551
        }
    552
    553
        function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal pure {
    554
            _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,uint256)", p0, p1, p2, p3));
    555
        }
    556
    557
        function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal pure {
    558
            _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,string)", p0, p1, p2, p3));
    559
        }
    560
    561
        function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal pure {
    562
            _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,bool)", p0, p1, p2, p3));
    563
        }
    564
    565
        function log(uint256 p0, uint256 p1, string memory p2, address p3) internal pure {
    566
            _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,address)", p0, p1, p2, p3));
    567
        }
    568
    569
        function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure {
    570
            _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,uint256)", p0, p1, p2, p3));
    571
        }
    572
    573
        function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal pure {
    574
            _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,string)", p0, p1, p2, p3));
    575
        }
    576
    577
        function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure {
    578
            _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,bool)", p0, p1, p2, p3));
    579
        }
    580
    581
        function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure {
    582
            _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,address)", p0, p1, p2, p3));
    583
        }
    584
    585
        function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure {
    586
            _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,uint256)", p0, p1, p2, p3));
    587
        }
    588
    589
        function log(uint256 p0, uint256 p1, address p2, string memory p3) internal pure {
    590
            _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,string)", p0, p1, p2, p3));
    591
        }
    592
    593
        function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure {
    594
            _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,bool)", p0, p1, p2, p3));
    595
        }
    596
    597
        function log(uint256 p0, uint256 p1, address p2, address p3) internal pure {
    598
            _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,address)", p0, p1, p2, p3));
    599
        }
    600
    601
        function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal pure {
    602
            _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,uint256)", p0, p1, p2, p3));
    603
        }
    604
    605
        function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal pure {
    606
            _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,string)", p0, p1, p2, p3));
    607
        }
    608
    609
        function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal pure {
    610
            _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,bool)", p0, p1, p2, p3));
    611
        }
    612
    613
        function log(uint256 p0, string memory p1, uint256 p2, address p3) internal pure {
    614
            _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,address)", p0, p1, p2, p3));
    615
        }
    616
    617
        function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal pure {
    618
            _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,uint256)", p0, p1, p2, p3));
    619
        }
    620
    621
        function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal pure {
    622
            _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,string)", p0, p1, p2, p3));
    623
        }
    624
    625
        function log(uint256 p0, string memory p1, string memory p2, bool p3) internal pure {
    626
            _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,bool)", p0, p1, p2, p3));
    627
        }
    628
    629
        function log(uint256 p0, string memory p1, string memory p2, address p3) internal pure {
    630
            _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,address)", p0, p1, p2, p3));
    631
        }
    632
    633
        function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal pure {
    634
            _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,uint256)", p0, p1, p2, p3));
    635
        }
    636
    637
        function log(uint256 p0, string memory p1, bool p2, string memory p3) internal pure {
    638
            _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,string)", p0, p1, p2, p3));
    639
        }
    640
    641
        function log(uint256 p0, string memory p1, bool p2, bool p3) internal pure {
    642
            _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,bool)", p0, p1, p2, p3));
    643
        }
    644
    645
        function log(uint256 p0, string memory p1, bool p2, address p3) internal pure {
    646
            _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,address)", p0, p1, p2, p3));
    647
        }
    648
    649
        function log(uint256 p0, string memory p1, address p2, uint256 p3) internal pure {
    650
            _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,uint256)", p0, p1, p2, p3));
    651
        }
    652
    653
        function log(uint256 p0, string memory p1, address p2, string memory p3) internal pure {
    654
            _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,string)", p0, p1, p2, p3));
    655
        }
    656
    657
        function log(uint256 p0, string memory p1, address p2, bool p3) internal pure {
    658
            _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,bool)", p0, p1, p2, p3));
    659
        }
    660
    661
        function log(uint256 p0, string memory p1, address p2, address p3) internal pure {
    662
            _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,address)", p0, p1, p2, p3));
    663
        }
    664
    665
        function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure {
    666
            _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,uint256)", p0, p1, p2, p3));
    667
        }
    668
    669
        function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal pure {
    670
            _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,string)", p0, p1, p2, p3));
    671
        }
    672
    673
        function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure {
    674
            _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,bool)", p0, p1, p2, p3));
    675
        }
    676
    677
        function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure {
    678
            _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,address)", p0, p1, p2, p3));
    679
        }
    680
    681
        function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal pure {
    682
            _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,uint256)", p0, p1, p2, p3));
    683
        }
    684
    685
        function log(uint256 p0, bool p1, string memory p2, string memory p3) internal pure {
    686
            _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,string)", p0, p1, p2, p3));
    687
        }
    688
    689
        function log(uint256 p0, bool p1, string memory p2, bool p3) internal pure {
    690
            _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,bool)", p0, p1, p2, p3));
    691
        }
    692
    693
        function log(uint256 p0, bool p1, string memory p2, address p3) internal pure {
    694
            _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,address)", p0, p1, p2, p3));
    695
        }
    696
    697
        function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure {
    698
            _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,uint256)", p0, p1, p2, p3));
    699
        }
    700
    701
        function log(uint256 p0, bool p1, bool p2, string memory p3) internal pure {
    702
            _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,string)", p0, p1, p2, p3));
    703
        }
    704
    705
        function log(uint256 p0, bool p1, bool p2, bool p3) internal pure {
    706
            _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,bool)", p0, p1, p2, p3));
    707
        }
    708
    709
        function log(uint256 p0, bool p1, bool p2, address p3) internal pure {
    710
            _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,address)", p0, p1, p2, p3));
    711
        }
    712
    713
        function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure {
    714
            _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,uint256)", p0, p1, p2, p3));
    715
        }
    716
    717
        function log(uint256 p0, bool p1, address p2, string memory p3) internal pure {
    718
            _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,string)", p0, p1, p2, p3));
    719
        }
    720
    721
        function log(uint256 p0, bool p1, address p2, bool p3) internal pure {
    722
            _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,bool)", p0, p1, p2, p3));
    723
        }
    724
    725
        function log(uint256 p0, bool p1, address p2, address p3) internal pure {
    726
            _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,address)", p0, p1, p2, p3));
    727
        }
    728
    729
        function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure {
    730
            _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,uint256)", p0, p1, p2, p3));
    731
        }
    732
    733
        function log(uint256 p0, address p1, uint256 p2, string memory p3) internal pure {
    734
            _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,string)", p0, p1, p2, p3));
    735
        }
    736
    737
        function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure {
    738
            _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,bool)", p0, p1, p2, p3));
    739
        }
    740
    741
        function log(uint256 p0, address p1, uint256 p2, address p3) internal pure {
    742
            _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,address)", p0, p1, p2, p3));
    743
        }
    744
    745
        function log(uint256 p0, address p1, string memory p2, uint256 p3) internal pure {
    746
            _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,uint256)", p0, p1, p2, p3));
    747
        }
    748
    749
        function log(uint256 p0, address p1, string memory p2, string memory p3) internal pure {
    750
            _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,string)", p0, p1, p2, p3));
    751
        }
    752
    753
        function log(uint256 p0, address p1, string memory p2, bool p3) internal pure {
    754
            _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,bool)", p0, p1, p2, p3));
    755
        }
    756
    757
        function log(uint256 p0, address p1, string memory p2, address p3) internal pure {
    758
            _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,address)", p0, p1, p2, p3));
    759
        }
    760
    761
        function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure {
    762
            _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,uint256)", p0, p1, p2, p3));
    763
        }
    764
    765
        function log(uint256 p0, address p1, bool p2, string memory p3) internal pure {
    766
            _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,string)", p0, p1, p2, p3));
    767
        }
    768
    769
        function log(uint256 p0, address p1, bool p2, bool p3) internal pure {
    770
            _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,bool)", p0, p1, p2, p3));
    771
        }
    772
    773
        function log(uint256 p0, address p1, bool p2, address p3) internal pure {
    774
            _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,address)", p0, p1, p2, p3));
    775
        }
    776
    777
        function log(uint256 p0, address p1, address p2, uint256 p3) internal pure {
    778
            _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,uint256)", p0, p1, p2, p3));
    779
        }
    780
    781
        function log(uint256 p0, address p1, address p2, string memory p3) internal pure {
    782
            _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,string)", p0, p1, p2, p3));
    783
        }
    784
    785
        function log(uint256 p0, address p1, address p2, bool p3) internal pure {
    786
            _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,bool)", p0, p1, p2, p3));
    787
        }
    788
    789
        function log(uint256 p0, address p1, address p2, address p3) internal pure {
    790
            _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,address)", p0, p1, p2, p3));
    791
        }
    792
    793
        function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
    794
            _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,uint256)", p0, p1, p2, p3));
    795
        }
    796
    797
        function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal pure {
    798
            _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,string)", p0, p1, p2, p3));
    799
        }
    800
    801
        function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal pure {
    802
            _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,bool)", p0, p1, p2, p3));
    803
        }
    804
    805
        function log(string memory p0, uint256 p1, uint256 p2, address p3) internal pure {
    806
            _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,address)", p0, p1, p2, p3));
    807
        }
    808
    809
        function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal pure {
    810
            _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,uint256)", p0, p1, p2, p3));
    811
        }
    812
    813
        function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal pure {
    814
            _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,string)", p0, p1, p2, p3));
    815
        }
    816
    817
        function log(string memory p0, uint256 p1, string memory p2, bool p3) internal pure {
    818
            _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,bool)", p0, p1, p2, p3));
    819
        }
    820
    821
        function log(string memory p0, uint256 p1, string memory p2, address p3) internal pure {
    822
            _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,address)", p0, p1, p2, p3));
    823
        }
    824
    825
        function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal pure {
    826
            _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,uint256)", p0, p1, p2, p3));
    827
        }
    828
    829
        function log(string memory p0, uint256 p1, bool p2, string memory p3) internal pure {
    830
            _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,string)", p0, p1, p2, p3));
    831
        }
    832
    833
        function log(string memory p0, uint256 p1, bool p2, bool p3) internal pure {
    834
            _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,bool)", p0, p1, p2, p3));
    835
        }
    836
    837
        function log(string memory p0, uint256 p1, bool p2, address p3) internal pure {
    838
            _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,address)", p0, p1, p2, p3));
    839
        }
    840
    841
        function log(string memory p0, uint256 p1, address p2, uint256 p3) internal pure {
    842
            _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,uint256)", p0, p1, p2, p3));
    843
        }
    844
    845
        function log(string memory p0, uint256 p1, address p2, string memory p3) internal pure {
    846
            _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,string)", p0, p1, p2, p3));
    847
        }
    848
    849
        function log(string memory p0, uint256 p1, address p2, bool p3) internal pure {
    850
            _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,bool)", p0, p1, p2, p3));
    851
        }
    852
    853
        function log(string memory p0, uint256 p1, address p2, address p3) internal pure {
    854
            _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,address)", p0, p1, p2, p3));
    855
        }
    856
    857
        function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal pure {
    858
            _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,uint256)", p0, p1, p2, p3));
    859
        }
    860
    861
        function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal pure {
    862
            _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,string)", p0, p1, p2, p3));
    863
        }
    864
    865
        function log(string memory p0, string memory p1, uint256 p2, bool p3) internal pure {
    866
            _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,bool)", p0, p1, p2, p3));
    867
        }
    868
    869
        function log(string memory p0, string memory p1, uint256 p2, address p3) internal pure {
    870
            _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,address)", p0, p1, p2, p3));
    871
        }
    872
    873
        function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal pure {
    874
            _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint256)", p0, p1, p2, p3));
    875
        }
    876
    877
        function log(string memory p0, string memory p1, string memory p2, string memory p3) internal pure {
    878
            _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3));
    879
        }
    880
    881
        function log(string memory p0, string memory p1, string memory p2, bool p3) internal pure {
    882
            _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3));
    883
        }
    884
    885
        function log(string memory p0, string memory p1, string memory p2, address p3) internal pure {
    886
            _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3));
    887
        }
    888
    889
        function log(string memory p0, string memory p1, bool p2, uint256 p3) internal pure {
    890
            _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint256)", p0, p1, p2, p3));
    891
        }
    892
    893
        function log(string memory p0, string memory p1, bool p2, string memory p3) internal pure {
    894
            _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3));
    895
        }
    896
    897
        function log(string memory p0, string memory p1, bool p2, bool p3) internal pure {
    898
            _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3));
    899
        }
    900
    901
        function log(string memory p0, string memory p1, bool p2, address p3) internal pure {
    902
            _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3));
    903
        }
    904
    905
        function log(string memory p0, string memory p1, address p2, uint256 p3) internal pure {
    906
            _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint256)", p0, p1, p2, p3));
    907
        }
    908
    909
        function log(string memory p0, string memory p1, address p2, string memory p3) internal pure {
    910
            _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3));
    911
        }
    912
    913
        function log(string memory p0, string memory p1, address p2, bool p3) internal pure {
    914
            _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3));
    915
        }
    916
    917
        function log(string memory p0, string memory p1, address p2, address p3) internal pure {
    918
            _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3));
    919
        }
    920
    921
        function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal pure {
    922
            _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,uint256)", p0, p1, p2, p3));
    923
        }
    924
    925
        function log(string memory p0, bool p1, uint256 p2, string memory p3) internal pure {
    926
            _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,string)", p0, p1, p2, p3));
    927
        }
    928
    929
        function log(string memory p0, bool p1, uint256 p2, bool p3) internal pure {
    930
            _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,bool)", p0, p1, p2, p3));
    931
        }
    932
    933
        function log(string memory p0, bool p1, uint256 p2, address p3) internal pure {
    934
            _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,address)", p0, p1, p2, p3));
    935
        }
    936
    937
        function log(string memory p0, bool p1, string memory p2, uint256 p3) internal pure {
    938
            _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint256)", p0, p1, p2, p3));
    939
        }
    940
    941
        function log(string memory p0, bool p1, string memory p2, string memory p3) internal pure {
    942
            _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3));
    943
        }
    944
    945
        function log(string memory p0, bool p1, string memory p2, bool p3) internal pure {
    946
            _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3));
    947
        }
    948
    949
        function log(string memory p0, bool p1, string memory p2, address p3) internal pure {
    950
            _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3));
    951
        }
    952
    953
        function log(string memory p0, bool p1, bool p2, uint256 p3) internal pure {
    954
            _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint256)", p0, p1, p2, p3));
    955
        }
    956
    957
        function log(string memory p0, bool p1, bool p2, string memory p3) internal pure {
    958
            _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3));
    959
        }
    960
    961
        function log(string memory p0, bool p1, bool p2, bool p3) internal pure {
    962
            _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3));
    963
        }
    964
    965
        function log(string memory p0, bool p1, bool p2, address p3) internal pure {
    966
            _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3));
    967
        }
    968
    969
        function log(string memory p0, bool p1, address p2, uint256 p3) internal pure {
    970
            _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint256)", p0, p1, p2, p3));
    971
        }
    972
    973
        function log(string memory p0, bool p1, address p2, string memory p3) internal pure {
    974
            _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3));
    975
        }
    976
    977
        function log(string memory p0, bool p1, address p2, bool p3) internal pure {
    978
            _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3));
    979
        }
    980
    981
        function log(string memory p0, bool p1, address p2, address p3) internal pure {
    982
            _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3));
    983
        }
    984
    985
        function log(string memory p0, address p1, uint256 p2, uint256 p3) internal pure {
    986
            _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,uint256)", p0, p1, p2, p3));
    987
        }
    988
    989
        function log(string memory p0, address p1, uint256 p2, string memory p3) internal pure {
    990
            _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,string)", p0, p1, p2, p3));
    991
        }
    992
    993
        function log(string memory p0, address p1, uint256 p2, bool p3) internal pure {
    994
            _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,bool)", p0, p1, p2, p3));
    995
        }
    996
    997
        function log(string memory p0, address p1, uint256 p2, address p3) internal pure {
    998
            _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,address)", p0, p1, p2, p3));
    999
        }
    1000
    1001
        function log(string memory p0, address p1, string memory p2, uint256 p3) internal pure {
    1002
            _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint256)", p0, p1, p2, p3));
    1003
        }
    1004
    1005
        function log(string memory p0, address p1, string memory p2, string memory p3) internal pure {
    1006
            _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3));
    1007
        }
    1008
    1009
        function log(string memory p0, address p1, string memory p2, bool p3) internal pure {
    1010
            _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3));
    1011
        }
    1012
    1013
        function log(string memory p0, address p1, string memory p2, address p3) internal pure {
    1014
            _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3));
    1015
        }
    1016
    1017
        function log(string memory p0, address p1, bool p2, uint256 p3) internal pure {
    1018
            _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint256)", p0, p1, p2, p3));
    1019
        }
    1020
    1021
        function log(string memory p0, address p1, bool p2, string memory p3) internal pure {
    1022
            _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3));
    1023
        }
    1024
    1025
        function log(string memory p0, address p1, bool p2, bool p3) internal pure {
    1026
            _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3));
    1027
        }
    1028
    1029
        function log(string memory p0, address p1, bool p2, address p3) internal pure {
    1030
            _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3));
    1031
        }
    1032
    1033
        function log(string memory p0, address p1, address p2, uint256 p3) internal pure {
    1034
            _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint256)", p0, p1, p2, p3));
    1035
        }
    1036
    1037
        function log(string memory p0, address p1, address p2, string memory p3) internal pure {
    1038
            _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3));
    1039
        }
    1040
    1041
        function log(string memory p0, address p1, address p2, bool p3) internal pure {
    1042
            _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3));
    1043
        }
    1044
    1045
        function log(string memory p0, address p1, address p2, address p3) internal pure {
    1046
            _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3));
    1047
        }
    1048
    1049
        function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
    1050
            _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,uint256)", p0, p1, p2, p3));
    1051
        }
    1052
    1053
        function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal pure {
    1054
            _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,string)", p0, p1, p2, p3));
    1055
        }
    1056
    1057
        function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure {
    1058
            _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,bool)", p0, p1, p2, p3));
    1059
        }
    1060
    1061
        function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure {
    1062
            _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,address)", p0, p1, p2, p3));
    1063
        }
    1064
    1065
        function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal pure {
    1066
            _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,uint256)", p0, p1, p2, p3));
    1067
        }
    1068
    1069
        function log(bool p0, uint256 p1, string memory p2, string memory p3) internal pure {
    1070
            _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,string)", p0, p1, p2, p3));
    1071
        }
    1072
    1073
        function log(bool p0, uint256 p1, string memory p2, bool p3) internal pure {
    1074
            _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,bool)", p0, p1, p2, p3));
    1075
        }
    1076
    1077
        function log(bool p0, uint256 p1, string memory p2, address p3) internal pure {
    1078
            _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,address)", p0, p1, p2, p3));
    1079
        }
    1080
    1081
        function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure {
    1082
            _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,uint256)", p0, p1, p2, p3));
    1083
        }
    1084
    1085
        function log(bool p0, uint256 p1, bool p2, string memory p3) internal pure {
    1086
            _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,string)", p0, p1, p2, p3));
    1087
        }
    1088
    1089
        function log(bool p0, uint256 p1, bool p2, bool p3) internal pure {
    1090
            _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,bool)", p0, p1, p2, p3));
    1091
        }
    1092
    1093
        function log(bool p0, uint256 p1, bool p2, address p3) internal pure {
    1094
            _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,address)", p0, p1, p2, p3));
    1095
        }
    1096
    1097
        function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure {
    1098
            _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,uint256)", p0, p1, p2, p3));
    1099
        }
    1100
    1101
        function log(bool p0, uint256 p1, address p2, string memory p3) internal pure {
    1102
            _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,string)", p0, p1, p2, p3));
    1103
        }
    1104
    1105
        function log(bool p0, uint256 p1, address p2, bool p3) internal pure {
    1106
            _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,bool)", p0, p1, p2, p3));
    1107
        }
    1108
    1109
        function log(bool p0, uint256 p1, address p2, address p3) internal pure {
    1110
            _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,address)", p0, p1, p2, p3));
    1111
        }
    1112
    1113
        function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal pure {
    1114
            _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,uint256)", p0, p1, p2, p3));
    1115
        }
    1116
    1117
        function log(bool p0, string memory p1, uint256 p2, string memory p3) internal pure {
    1118
            _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,string)", p0, p1, p2, p3));
    1119
        }
    1120
    1121
        function log(bool p0, string memory p1, uint256 p2, bool p3) internal pure {
    1122
            _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,bool)", p0, p1, p2, p3));
    1123
        }
    1124
    1125
        function log(bool p0, string memory p1, uint256 p2, address p3) internal pure {
    1126
            _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,address)", p0, p1, p2, p3));
    1127
        }
    1128
    1129
        function log(bool p0, string memory p1, string memory p2, uint256 p3) internal pure {
    1130
            _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint256)", p0, p1, p2, p3));
    1131
        }
    1132
    1133
        function log(bool p0, string memory p1, string memory p2, string memory p3) internal pure {
    1134
            _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3));
    1135
        }
    1136
    1137
        function log(bool p0, string memory p1, string memory p2, bool p3) internal pure {
    1138
            _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3));
    1139
        }
    1140
    1141
        function log(bool p0, string memory p1, string memory p2, address p3) internal pure {
    1142
            _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3));
    1143
        }
    1144
    1145
        function log(bool p0, string memory p1, bool p2, uint256 p3) internal pure {
    1146
            _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint256)", p0, p1, p2, p3));
    1147
        }
    1148
    1149
        function log(bool p0, string memory p1, bool p2, string memory p3) internal pure {
    1150
            _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3));
    1151
        }
    1152
    1153
        function log(bool p0, string memory p1, bool p2, bool p3) internal pure {
    1154
            _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3));
    1155
        }
    1156
    1157
        function log(bool p0, string memory p1, bool p2, address p3) internal pure {
    1158
            _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3));
    1159
        }
    1160
    1161
        function log(bool p0, string memory p1, address p2, uint256 p3) internal pure {
    1162
            _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint256)", p0, p1, p2, p3));
    1163
        }
    1164
    1165
        function log(bool p0, string memory p1, address p2, string memory p3) internal pure {
    1166
            _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3));
    1167
        }
    1168
    1169
        function log(bool p0, string memory p1, address p2, bool p3) internal pure {
    1170
            _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3));
    1171
        }
    1172
    1173
        function log(bool p0, string memory p1, address p2, address p3) internal pure {
    1174
            _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3));
    1175
        }
    1176
    1177
        function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure {
    1178
            _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,uint256)", p0, p1, p2, p3));
    1179
        }
    1180
    1181
        function log(bool p0, bool p1, uint256 p2, string memory p3) internal pure {
    1182
            _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,string)", p0, p1, p2, p3));
    1183
        }
    1184
    1185
        function log(bool p0, bool p1, uint256 p2, bool p3) internal pure {
    1186
            _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,bool)", p0, p1, p2, p3));
    1187
        }
    1188
    1189
        function log(bool p0, bool p1, uint256 p2, address p3) internal pure {
    1190
            _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,address)", p0, p1, p2, p3));
    1191
        }
    1192
    1193
        function log(bool p0, bool p1, string memory p2, uint256 p3) internal pure {
    1194
            _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint256)", p0, p1, p2, p3));
    1195
        }
    1196
    1197
        function log(bool p0, bool p1, string memory p2, string memory p3) internal pure {
    1198
            _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3));
    1199
        }
    1200
    1201
        function log(bool p0, bool p1, string memory p2, bool p3) internal pure {
    1202
            _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3));
    1203
        }
    1204
    1205
        function log(bool p0, bool p1, string memory p2, address p3) internal pure {
    1206
            _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3));
    1207
        }
    1208
    1209
        function log(bool p0, bool p1, bool p2, uint256 p3) internal pure {
    1210
            _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint256)", p0, p1, p2, p3));
    1211
        }
    1212
    1213
        function log(bool p0, bool p1, bool p2, string memory p3) internal pure {
    1214
            _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3));
    1215
        }
    1216
    1217
        function log(bool p0, bool p1, bool p2, bool p3) internal pure {
    1218
            _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3));
    1219
        }
    1220
    1221
        function log(bool p0, bool p1, bool p2, address p3) internal pure {
    1222
            _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3));
    1223
        }
    1224
    1225
        function log(bool p0, bool p1, address p2, uint256 p3) internal pure {
    1226
            _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint256)", p0, p1, p2, p3));
    1227
        }
    1228
    1229
        function log(bool p0, bool p1, address p2, string memory p3) internal pure {
    1230
            _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3));
    1231
        }
    1232
    1233
        function log(bool p0, bool p1, address p2, bool p3) internal pure {
    1234
            _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3));
    1235
        }
    1236
    1237
        function log(bool p0, bool p1, address p2, address p3) internal pure {
    1238
            _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3));
    1239
        }
    1240
    1241
        function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure {
    1242
            _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,uint256)", p0, p1, p2, p3));
    1243
        }
    1244
    1245
        function log(bool p0, address p1, uint256 p2, string memory p3) internal pure {
    1246
            _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,string)", p0, p1, p2, p3));
    1247
        }
    1248
    1249
        function log(bool p0, address p1, uint256 p2, bool p3) internal pure {
    1250
            _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,bool)", p0, p1, p2, p3));
    1251
        }
    1252
    1253
        function log(bool p0, address p1, uint256 p2, address p3) internal pure {
    1254
            _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,address)", p0, p1, p2, p3));
    1255
        }
    1256
    1257
        function log(bool p0, address p1, string memory p2, uint256 p3) internal pure {
    1258
            _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint256)", p0, p1, p2, p3));
    1259
        }
    1260
    1261
        function log(bool p0, address p1, string memory p2, string memory p3) internal pure {
    1262
            _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3));
    1263
        }
    1264
    1265
        function log(bool p0, address p1, string memory p2, bool p3) internal pure {
    1266
            _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3));
    1267
        }
    1268
    1269
        function log(bool p0, address p1, string memory p2, address p3) internal pure {
    1270
            _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3));
    1271
        }
    1272
    1273
        function log(bool p0, address p1, bool p2, uint256 p3) internal pure {
    1274
            _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint256)", p0, p1, p2, p3));
    1275
        }
    1276
    1277
        function log(bool p0, address p1, bool p2, string memory p3) internal pure {
    1278
            _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3));
    1279
        }
    1280
    1281
        function log(bool p0, address p1, bool p2, bool p3) internal pure {
    1282
            _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3));
    1283
        }
    1284
    1285
        function log(bool p0, address p1, bool p2, address p3) internal pure {
    1286
            _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3));
    1287
        }
    1288
    1289
        function log(bool p0, address p1, address p2, uint256 p3) internal pure {
    1290
            _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint256)", p0, p1, p2, p3));
    1291
        }
    1292
    1293
        function log(bool p0, address p1, address p2, string memory p3) internal pure {
    1294
            _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3));
    1295
        }
    1296
    1297
        function log(bool p0, address p1, address p2, bool p3) internal pure {
    1298
            _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3));
    1299
        }
    1300
    1301
        function log(bool p0, address p1, address p2, address p3) internal pure {
    1302
            _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3));
    1303
        }
    1304
    1305
        function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
    1306
            _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,uint256)", p0, p1, p2, p3));
    1307
        }
    1308
    1309
        function log(address p0, uint256 p1, uint256 p2, string memory p3) internal pure {
    1310
            _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,string)", p0, p1, p2, p3));
    1311
        }
    1312
    1313
        function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure {
    1314
            _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,bool)", p0, p1, p2, p3));
    1315
        }
    1316
    1317
        function log(address p0, uint256 p1, uint256 p2, address p3) internal pure {
    1318
            _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,address)", p0, p1, p2, p3));
    1319
        }
    1320
    1321
        function log(address p0, uint256 p1, string memory p2, uint256 p3) internal pure {
    1322
            _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,uint256)", p0, p1, p2, p3));
    1323
        }
    1324
    1325
        function log(address p0, uint256 p1, string memory p2, string memory p3) internal pure {
    1326
            _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,string)", p0, p1, p2, p3));
    1327
        }
    1328
    1329
        function log(address p0, uint256 p1, string memory p2, bool p3) internal pure {
    1330
            _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,bool)", p0, p1, p2, p3));
    1331
        }
    1332
    1333
        function log(address p0, uint256 p1, string memory p2, address p3) internal pure {
    1334
            _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,address)", p0, p1, p2, p3));
    1335
        }
    1336
    1337
        function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure {
    1338
            _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,uint256)", p0, p1, p2, p3));
    1339
        }
    1340
    1341
        function log(address p0, uint256 p1, bool p2, string memory p3) internal pure {
    1342
            _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,string)", p0, p1, p2, p3));
    1343
        }
    1344
    1345
        function log(address p0, uint256 p1, bool p2, bool p3) internal pure {
    1346
            _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,bool)", p0, p1, p2, p3));
    1347
        }
    1348
    1349
        function log(address p0, uint256 p1, bool p2, address p3) internal pure {
    1350
            _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,address)", p0, p1, p2, p3));
    1351
        }
    1352
    1353
        function log(address p0, uint256 p1, address p2, uint256 p3) internal pure {
    1354
            _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,uint256)", p0, p1, p2, p3));
    1355
        }
    1356
    1357
        function log(address p0, uint256 p1, address p2, string memory p3) internal pure {
    1358
            _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,string)", p0, p1, p2, p3));
    1359
        }
    1360
    1361
        function log(address p0, uint256 p1, address p2, bool p3) internal pure {
    1362
            _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,bool)", p0, p1, p2, p3));
    1363
        }
    1364
    1365
        function log(address p0, uint256 p1, address p2, address p3) internal pure {
    1366
            _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,address)", p0, p1, p2, p3));
    1367
        }
    1368
    1369
        function log(address p0, string memory p1, uint256 p2, uint256 p3) internal pure {
    1370
            _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,uint256)", p0, p1, p2, p3));
    1371
        }
    1372
    1373
        function log(address p0, string memory p1, uint256 p2, string memory p3) internal pure {
    1374
            _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,string)", p0, p1, p2, p3));
    1375
        }
    1376
    1377
        function log(address p0, string memory p1, uint256 p2, bool p3) internal pure {
    1378
            _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,bool)", p0, p1, p2, p3));
    1379
        }
    1380
    1381
        function log(address p0, string memory p1, uint256 p2, address p3) internal pure {
    1382
            _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,address)", p0, p1, p2, p3));
    1383
        }
    1384
    1385
        function log(address p0, string memory p1, string memory p2, uint256 p3) internal pure {
    1386
            _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint256)", p0, p1, p2, p3));
    1387
        }
    1388
    1389
        function log(address p0, string memory p1, string memory p2, string memory p3) internal pure {
    1390
            _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3));
    1391
        }
    1392
    1393
        function log(address p0, string memory p1, string memory p2, bool p3) internal pure {
    1394
            _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3));
    1395
        }
    1396
    1397
        function log(address p0, string memory p1, string memory p2, address p3) internal pure {
    1398
            _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3));
    1399
        }
    1400
    1401
        function log(address p0, string memory p1, bool p2, uint256 p3) internal pure {
    1402
            _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint256)", p0, p1, p2, p3));
    1403
        }
    1404
    1405
        function log(address p0, string memory p1, bool p2, string memory p3) internal pure {
    1406
            _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3));
    1407
        }
    1408
    1409
        function log(address p0, string memory p1, bool p2, bool p3) internal pure {
    1410
            _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3));
    1411
        }
    1412
    1413
        function log(address p0, string memory p1, bool p2, address p3) internal pure {
    1414
            _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3));
    1415
        }
    1416
    1417
        function log(address p0, string memory p1, address p2, uint256 p3) internal pure {
    1418
            _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint256)", p0, p1, p2, p3));
    1419
        }
    1420
    1421
        function log(address p0, string memory p1, address p2, string memory p3) internal pure {
    1422
            _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3));
    1423
        }
    1424
    1425
        function log(address p0, string memory p1, address p2, bool p3) internal pure {
    1426
            _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3));
    1427
        }
    1428
    1429
        function log(address p0, string memory p1, address p2, address p3) internal pure {
    1430
            _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3));
    1431
        }
    1432
    1433
        function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure {
    1434
            _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,uint256)", p0, p1, p2, p3));
    1435
        }
    1436
    1437
        function log(address p0, bool p1, uint256 p2, string memory p3) internal pure {
    1438
            _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,string)", p0, p1, p2, p3));
    1439
        }
    1440
    1441
        function log(address p0, bool p1, uint256 p2, bool p3) internal pure {
    1442
            _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,bool)", p0, p1, p2, p3));
    1443
        }
    1444
    1445
        function log(address p0, bool p1, uint256 p2, address p3) internal pure {
    1446
            _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,address)", p0, p1, p2, p3));
    1447
        }
    1448
    1449
        function log(address p0, bool p1, string memory p2, uint256 p3) internal pure {
    1450
            _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint256)", p0, p1, p2, p3));
    1451
        }
    1452
    1453
        function log(address p0, bool p1, string memory p2, string memory p3) internal pure {
    1454
            _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3));
    1455
        }
    1456
    1457
        function log(address p0, bool p1, string memory p2, bool p3) internal pure {
    1458
            _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3));
    1459
        }
    1460
    1461
        function log(address p0, bool p1, string memory p2, address p3) internal pure {
    1462
            _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3));
    1463
        }
    1464
    1465
        function log(address p0, bool p1, bool p2, uint256 p3) internal pure {
    1466
            _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint256)", p0, p1, p2, p3));
    1467
        }
    1468
    1469
        function log(address p0, bool p1, bool p2, string memory p3) internal pure {
    1470
            _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3));
    1471
        }
    1472
    1473
        function log(address p0, bool p1, bool p2, bool p3) internal pure {
    1474
            _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3));
    1475
        }
    1476
    1477
        function log(address p0, bool p1, bool p2, address p3) internal pure {
    1478
            _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3));
    1479
        }
    1480
    1481
        function log(address p0, bool p1, address p2, uint256 p3) internal pure {
    1482
            _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint256)", p0, p1, p2, p3));
    1483
        }
    1484
    1485
        function log(address p0, bool p1, address p2, string memory p3) internal pure {
    1486
            _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3));
    1487
        }
    1488
    1489
        function log(address p0, bool p1, address p2, bool p3) internal pure {
    1490
            _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3));
    1491
        }
    1492
    1493
        function log(address p0, bool p1, address p2, address p3) internal pure {
    1494
            _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3));
    1495
        }
    1496
    1497
        function log(address p0, address p1, uint256 p2, uint256 p3) internal pure {
    1498
            _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,uint256)", p0, p1, p2, p3));
    1499
        }
    1500
    1501
        function log(address p0, address p1, uint256 p2, string memory p3) internal pure {
    1502
            _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,string)", p0, p1, p2, p3));
    1503
        }
    1504
    1505
        function log(address p0, address p1, uint256 p2, bool p3) internal pure {
    1506
            _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,bool)", p0, p1, p2, p3));
    1507
        }
    1508
    1509
        function log(address p0, address p1, uint256 p2, address p3) internal pure {
    1510
            _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,address)", p0, p1, p2, p3));
    1511
        }
    1512
    1513
        function log(address p0, address p1, string memory p2, uint256 p3) internal pure {
    1514
            _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint256)", p0, p1, p2, p3));
    1515
        }
    1516
    1517
        function log(address p0, address p1, string memory p2, string memory p3) internal pure {
    1518
            _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3));
    1519
        }
    1520
    1521
        function log(address p0, address p1, string memory p2, bool p3) internal pure {
    1522
            _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3));
    1523
        }
    1524
    1525
        function log(address p0, address p1, string memory p2, address p3) internal pure {
    1526
            _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3));
    1527
        }
    1528
    1529
        function log(address p0, address p1, bool p2, uint256 p3) internal pure {
    1530
            _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint256)", p0, p1, p2, p3));
    1531
        }
    1532
    1533
        function log(address p0, address p1, bool p2, string memory p3) internal pure {
    1534
            _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3));
    1535
        }
    1536
    1537
        function log(address p0, address p1, bool p2, bool p3) internal pure {
    1538
            _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3));
    1539
        }
    1540
    1541
        function log(address p0, address p1, bool p2, address p3) internal pure {
    1542
            _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3));
    1543
        }
    1544
    1545
        function log(address p0, address p1, address p2, uint256 p3) internal pure {
    1546
            _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint256)", p0, p1, p2, p3));
    1547
        }
    1548
    1549
        function log(address p0, address p1, address p2, string memory p3) internal pure {
    1550
            _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3));
    1551
        }
    1552
    1553
        function log(address p0, address p1, address p2, bool p3) internal pure {
    1554
            _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3));
    1555
        }
    1556
    1557
        function log(address p0, address p1, address p2, address p3) internal pure {
    1558
            _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3));
    1559
        }
    1560
    }
    1561
    0.0% lib/forge-std/src/console2.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    pragma solidity >=0.4.22 <0.9.0;
    3
    4
    import {console as console2} from "./console.sol";
    5
    0.0% lib/forge-std/src/interfaces/IMulticall3.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    pragma solidity >=0.6.2 <0.9.0;
    3
    4
    pragma experimental ABIEncoderV2;
    5
    6
    interface IMulticall3 {
    7
        struct Call {
    8
            address target;
    9
            bytes callData;
    10
        }
    11
    12
        struct Call3 {
    13
            address target;
    14
            bool allowFailure;
    15
            bytes callData;
    16
        }
    17
    18
        struct Call3Value {
    19
            address target;
    20
            bool allowFailure;
    21
            uint256 value;
    22
            bytes callData;
    23
        }
    24
    25
        struct Result {
    26
            bool success;
    27
            bytes returnData;
    28
        }
    29
    30
        function aggregate(Call[] calldata calls)
    31
            external
    32
            payable
    33
            returns (uint256 blockNumber, bytes[] memory returnData);
    34
    35
        function aggregate3(Call3[] calldata calls) external payable returns (Result[] memory returnData);
    36
    37
        function aggregate3Value(Call3Value[] calldata calls) external payable returns (Result[] memory returnData);
    38
    39
        function blockAndAggregate(Call[] calldata calls)
    40
            external
    41
            payable
    42
            returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData);
    43
    44
        function getBasefee() external view returns (uint256 basefee);
    45
    46
        function getBlockHash(uint256 blockNumber) external view returns (bytes32 blockHash);
    47
    48
        function getBlockNumber() external view returns (uint256 blockNumber);
    49
    50
        function getChainId() external view returns (uint256 chainid);
    51
    52
        function getCurrentBlockCoinbase() external view returns (address coinbase);
    53
    54
        function getCurrentBlockDifficulty() external view returns (uint256 difficulty);
    55
    56
        function getCurrentBlockGasLimit() external view returns (uint256 gaslimit);
    57
    58
        function getCurrentBlockTimestamp() external view returns (uint256 timestamp);
    59
    60
        function getEthBalance(address addr) external view returns (uint256 balance);
    61
    62
        function getLastBlockHash() external view returns (bytes32 blockHash);
    63
    64
        function tryAggregate(bool requireSuccess, Call[] calldata calls)
    65
            external
    66
            payable
    67
            returns (Result[] memory returnData);
    68
    69
        function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls)
    70
            external
    71
            payable
    72
            returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData);
    73
    }
    74
    100.0% lib/forge-std/src/safeconsole.sol
    Lines covered: 1 / 1 (100.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    pragma solidity >=0.6.2 <0.9.0;
    3
    4
    /// @author philogy <https://github.com/philogy>
    5
    /// @dev Code generated automatically by script.
    6
    library safeconsole {
    7
        uint256 constant CONSOLE_ADDR = 0x000000000000000000000000000000000000000000636F6e736F6c652e6c6f67;
    8
    9
        // Credit to [0age](https://twitter.com/z0age/status/1654922202930888704) and [0xdapper](https://github.com/foundry-rs/forge-std/pull/374)
    10
        // for the view-to-pure log trick.
    11
        function _sendLogPayload(uint256 offset, uint256 size) private pure {
    12
            function(uint256, uint256) internal view fnIn = _sendLogPayloadView;
    13
            function(uint256, uint256) internal pure pureSendLogPayload;
    14
            /// @solidity memory-safe-assembly
    15
            assembly {
    16
                pureSendLogPayload := fnIn
    17
            }
    18
            pureSendLogPayload(offset, size);
    19
        }
    20
    21
        function _sendLogPayloadView(uint256 offset, uint256 size) private view {
    22
            /// @solidity memory-safe-assembly
    23
            assembly {
    24
                pop(staticcall(gas(), CONSOLE_ADDR, offset, size, 0x0, 0x0))
    25
            }
    26
        }
    27
    28
        function _memcopy(uint256 fromOffset, uint256 toOffset, uint256 length) private pure {
    29
            function(uint256, uint256, uint256) internal view fnIn = _memcopyView;
    30
            function(uint256, uint256, uint256) internal pure pureMemcopy;
    31
            /// @solidity memory-safe-assembly
    32
            assembly {
    33
                pureMemcopy := fnIn
    34
            }
    35
            pureMemcopy(fromOffset, toOffset, length);
    36
        }
    37
    38
        function _memcopyView(uint256 fromOffset, uint256 toOffset, uint256 length) private view {
    39
            /// @solidity memory-safe-assembly
    40
            assembly {
    41
                pop(staticcall(gas(), 0x4, fromOffset, length, toOffset, length))
    42
            }
    43
        }
    44
    45
        function logMemory(uint256 offset, uint256 length) internal pure {
    46
            if (offset >= 0x60) {
    47
                // Sufficient memory before slice to prepare call header.
    48
                bytes32 m0;
    49
                bytes32 m1;
    50
                bytes32 m2;
    51
                /// @solidity memory-safe-assembly
    52
                assembly {
    53
                    m0 := mload(sub(offset, 0x60))
    54
                    m1 := mload(sub(offset, 0x40))
    55
                    m2 := mload(sub(offset, 0x20))
    56
                    // Selector of `log(bytes)`.
    57
                    mstore(sub(offset, 0x60), 0x0be77f56)
    58
                    mstore(sub(offset, 0x40), 0x20)
    59
                    mstore(sub(offset, 0x20), length)
    60
                }
    61
                _sendLogPayload(offset - 0x44, length + 0x44);
    62
                /// @solidity memory-safe-assembly
    63
                assembly {
    64
                    mstore(sub(offset, 0x60), m0)
    65
                    mstore(sub(offset, 0x40), m1)
    66
                    mstore(sub(offset, 0x20), m2)
    67
                }
    68
            } else {
    69
                // Insufficient space, so copy slice forward, add header and reverse.
    70
                bytes32 m0;
    71
                bytes32 m1;
    72
                bytes32 m2;
    73
                uint256 endOffset = offset + length;
    74
                /// @solidity memory-safe-assembly
    75
                assembly {
    76
                    m0 := mload(add(endOffset, 0x00))
    77
                    m1 := mload(add(endOffset, 0x20))
    78
                    m2 := mload(add(endOffset, 0x40))
    79
                }
    80
                _memcopy(offset, offset + 0x60, length);
    81
                /// @solidity memory-safe-assembly
    82
                assembly {
    83
                    // Selector of `log(bytes)`.
    84
                    mstore(add(offset, 0x00), 0x0be77f56)
    85
                    mstore(add(offset, 0x20), 0x20)
    86
                    mstore(add(offset, 0x40), length)
    87
                }
    88
                _sendLogPayload(offset + 0x1c, length + 0x44);
    89
                _memcopy(offset + 0x60, offset, length);
    90
                /// @solidity memory-safe-assembly
    91
                assembly {
    92
                    mstore(add(endOffset, 0x00), m0)
    93
                    mstore(add(endOffset, 0x20), m1)
    94
                    mstore(add(endOffset, 0x40), m2)
    95
                }
    96
            }
    97
        }
    98
    99
        function log(address p0) internal pure {
    100
            bytes32 m0;
    101
            bytes32 m1;
    102
            /// @solidity memory-safe-assembly
    103
            assembly {
    104
                m0 := mload(0x00)
    105
                m1 := mload(0x20)
    106
                // Selector of `log(address)`.
    107
                mstore(0x00, 0x2c2ecbc2)
    108
                mstore(0x20, p0)
    109
            }
    110
            _sendLogPayload(0x1c, 0x24);
    111
            /// @solidity memory-safe-assembly
    112
            assembly {
    113
                mstore(0x00, m0)
    114
                mstore(0x20, m1)
    115
            }
    116
        }
    117
    118
        function log(bool p0) internal pure {
    119
            bytes32 m0;
    120
            bytes32 m1;
    121
            /// @solidity memory-safe-assembly
    122
            assembly {
    123
                m0 := mload(0x00)
    124
                m1 := mload(0x20)
    125
                // Selector of `log(bool)`.
    126
                mstore(0x00, 0x32458eed)
    127
                mstore(0x20, p0)
    128
            }
    129
            _sendLogPayload(0x1c, 0x24);
    130
            /// @solidity memory-safe-assembly
    131
            assembly {
    132
                mstore(0x00, m0)
    133
                mstore(0x20, m1)
    134
            }
    135
        }
    136
    137
        function log(uint256 p0) internal pure {
    138
            bytes32 m0;
    139
            bytes32 m1;
    140
            /// @solidity memory-safe-assembly
    141
            assembly {
    142
                m0 := mload(0x00)
    143
                m1 := mload(0x20)
    144
                // Selector of `log(uint256)`.
    145
                mstore(0x00, 0xf82c50f1)
    146
                mstore(0x20, p0)
    147
            }
    148
            _sendLogPayload(0x1c, 0x24);
    149
            /// @solidity memory-safe-assembly
    150
            assembly {
    151
                mstore(0x00, m0)
    152
                mstore(0x20, m1)
    153
            }
    154
        }
    155
    156
        function log(bytes32 p0) internal pure {
    157
            bytes32 m0;
    158
            bytes32 m1;
    159
            bytes32 m2;
    160
            bytes32 m3;
    161
            /// @solidity memory-safe-assembly
    162
            assembly {
    163
                function writeString(pos, w) {
    164
                    let length := 0
    165
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    166
                    mstore(pos, length)
    167
                    let shift := sub(256, shl(3, length))
    168
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    169
                }
    170
                m0 := mload(0x00)
    171
                m1 := mload(0x20)
    172
                m2 := mload(0x40)
    173
                m3 := mload(0x60)
    174
                // Selector of `log(string)`.
    175
                mstore(0x00, 0x41304fac)
    176
                mstore(0x20, 0x20)
    177
                writeString(0x40, p0)
    178
            }
    179
            _sendLogPayload(0x1c, 0x64);
    180
            /// @solidity memory-safe-assembly
    181
            assembly {
    182
                mstore(0x00, m0)
    183
                mstore(0x20, m1)
    184
                mstore(0x40, m2)
    185
                mstore(0x60, m3)
    186
            }
    187
        }
    188
    189
        function log(address p0, address p1) internal pure {
    190
            bytes32 m0;
    191
            bytes32 m1;
    192
            bytes32 m2;
    193
            /// @solidity memory-safe-assembly
    194
            assembly {
    195
                m0 := mload(0x00)
    196
                m1 := mload(0x20)
    197
                m2 := mload(0x40)
    198
                // Selector of `log(address,address)`.
    199
                mstore(0x00, 0xdaf0d4aa)
    200
                mstore(0x20, p0)
    201
                mstore(0x40, p1)
    202
            }
    203
            _sendLogPayload(0x1c, 0x44);
    204
            /// @solidity memory-safe-assembly
    205
            assembly {
    206
                mstore(0x00, m0)
    207
                mstore(0x20, m1)
    208
                mstore(0x40, m2)
    209
            }
    210
        }
    211
    212
        function log(address p0, bool p1) internal pure {
    213
            bytes32 m0;
    214
            bytes32 m1;
    215
            bytes32 m2;
    216
            /// @solidity memory-safe-assembly
    217
            assembly {
    218
                m0 := mload(0x00)
    219
                m1 := mload(0x20)
    220
                m2 := mload(0x40)
    221
                // Selector of `log(address,bool)`.
    222
                mstore(0x00, 0x75b605d3)
    223
                mstore(0x20, p0)
    224
                mstore(0x40, p1)
    225
            }
    226
            _sendLogPayload(0x1c, 0x44);
    227
            /// @solidity memory-safe-assembly
    228
            assembly {
    229
                mstore(0x00, m0)
    230
                mstore(0x20, m1)
    231
                mstore(0x40, m2)
    232
            }
    233
        }
    234
    235
        function log(address p0, uint256 p1) internal pure {
    236
            bytes32 m0;
    237
            bytes32 m1;
    238
            bytes32 m2;
    239
            /// @solidity memory-safe-assembly
    240
            assembly {
    241
                m0 := mload(0x00)
    242
                m1 := mload(0x20)
    243
                m2 := mload(0x40)
    244
                // Selector of `log(address,uint256)`.
    245
                mstore(0x00, 0x8309e8a8)
    246
                mstore(0x20, p0)
    247
                mstore(0x40, p1)
    248
            }
    249
            _sendLogPayload(0x1c, 0x44);
    250
            /// @solidity memory-safe-assembly
    251
            assembly {
    252
                mstore(0x00, m0)
    253
                mstore(0x20, m1)
    254
                mstore(0x40, m2)
    255
            }
    256
        }
    257
    258
        function log(address p0, bytes32 p1) internal pure {
    259
            bytes32 m0;
    260
            bytes32 m1;
    261
            bytes32 m2;
    262
            bytes32 m3;
    263
            bytes32 m4;
    264
            /// @solidity memory-safe-assembly
    265
            assembly {
    266
                function writeString(pos, w) {
    267
                    let length := 0
    268
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    269
                    mstore(pos, length)
    270
                    let shift := sub(256, shl(3, length))
    271
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    272
                }
    273
                m0 := mload(0x00)
    274
                m1 := mload(0x20)
    275
                m2 := mload(0x40)
    276
                m3 := mload(0x60)
    277
                m4 := mload(0x80)
    278
                // Selector of `log(address,string)`.
    279
                mstore(0x00, 0x759f86bb)
    280
                mstore(0x20, p0)
    281
                mstore(0x40, 0x40)
    282
                writeString(0x60, p1)
    283
            }
    284
            _sendLogPayload(0x1c, 0x84);
    285
            /// @solidity memory-safe-assembly
    286
            assembly {
    287
                mstore(0x00, m0)
    288
                mstore(0x20, m1)
    289
                mstore(0x40, m2)
    290
                mstore(0x60, m3)
    291
                mstore(0x80, m4)
    292
            }
    293
        }
    294
    295
        function log(bool p0, address p1) internal pure {
    296
            bytes32 m0;
    297
            bytes32 m1;
    298
            bytes32 m2;
    299
            /// @solidity memory-safe-assembly
    300
            assembly {
    301
                m0 := mload(0x00)
    302
                m1 := mload(0x20)
    303
                m2 := mload(0x40)
    304
                // Selector of `log(bool,address)`.
    305
                mstore(0x00, 0x853c4849)
    306
                mstore(0x20, p0)
    307
                mstore(0x40, p1)
    308
            }
    309
            _sendLogPayload(0x1c, 0x44);
    310
            /// @solidity memory-safe-assembly
    311
            assembly {
    312
                mstore(0x00, m0)
    313
                mstore(0x20, m1)
    314
                mstore(0x40, m2)
    315
            }
    316
        }
    317
    318
        function log(bool p0, bool p1) internal pure {
    319
            bytes32 m0;
    320
            bytes32 m1;
    321
            bytes32 m2;
    322
            /// @solidity memory-safe-assembly
    323
            assembly {
    324
                m0 := mload(0x00)
    325
                m1 := mload(0x20)
    326
                m2 := mload(0x40)
    327
                // Selector of `log(bool,bool)`.
    328
                mstore(0x00, 0x2a110e83)
    329
                mstore(0x20, p0)
    330
                mstore(0x40, p1)
    331
            }
    332
            _sendLogPayload(0x1c, 0x44);
    333
            /// @solidity memory-safe-assembly
    334
            assembly {
    335
                mstore(0x00, m0)
    336
                mstore(0x20, m1)
    337
                mstore(0x40, m2)
    338
            }
    339
        }
    340
    341
        function log(bool p0, uint256 p1) internal pure {
    342
            bytes32 m0;
    343
            bytes32 m1;
    344
            bytes32 m2;
    345
            /// @solidity memory-safe-assembly
    346
            assembly {
    347
                m0 := mload(0x00)
    348
                m1 := mload(0x20)
    349
                m2 := mload(0x40)
    350
                // Selector of `log(bool,uint256)`.
    351
                mstore(0x00, 0x399174d3)
    352
                mstore(0x20, p0)
    353
                mstore(0x40, p1)
    354
            }
    355
            _sendLogPayload(0x1c, 0x44);
    356
            /// @solidity memory-safe-assembly
    357
            assembly {
    358
                mstore(0x00, m0)
    359
                mstore(0x20, m1)
    360
                mstore(0x40, m2)
    361
            }
    362
        }
    363
    364
        function log(bool p0, bytes32 p1) internal pure {
    365
            bytes32 m0;
    366
            bytes32 m1;
    367
            bytes32 m2;
    368
            bytes32 m3;
    369
            bytes32 m4;
    370
            /// @solidity memory-safe-assembly
    371
            assembly {
    372
                function writeString(pos, w) {
    373
                    let length := 0
    374
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    375
                    mstore(pos, length)
    376
                    let shift := sub(256, shl(3, length))
    377
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    378
                }
    379
                m0 := mload(0x00)
    380
                m1 := mload(0x20)
    381
                m2 := mload(0x40)
    382
                m3 := mload(0x60)
    383
                m4 := mload(0x80)
    384
                // Selector of `log(bool,string)`.
    385
                mstore(0x00, 0x8feac525)
    386
                mstore(0x20, p0)
    387
                mstore(0x40, 0x40)
    388
                writeString(0x60, p1)
    389
            }
    390
            _sendLogPayload(0x1c, 0x84);
    391
            /// @solidity memory-safe-assembly
    392
            assembly {
    393
                mstore(0x00, m0)
    394
                mstore(0x20, m1)
    395
                mstore(0x40, m2)
    396
                mstore(0x60, m3)
    397
                mstore(0x80, m4)
    398
            }
    399
        }
    400
    401
        function log(uint256 p0, address p1) internal pure {
    402
            bytes32 m0;
    403
            bytes32 m1;
    404
            bytes32 m2;
    405
            /// @solidity memory-safe-assembly
    406
            assembly {
    407
                m0 := mload(0x00)
    408
                m1 := mload(0x20)
    409
                m2 := mload(0x40)
    410
                // Selector of `log(uint256,address)`.
    411
                mstore(0x00, 0x69276c86)
    412
                mstore(0x20, p0)
    413
                mstore(0x40, p1)
    414
            }
    415
            _sendLogPayload(0x1c, 0x44);
    416
            /// @solidity memory-safe-assembly
    417
            assembly {
    418
                mstore(0x00, m0)
    419
                mstore(0x20, m1)
    420
                mstore(0x40, m2)
    421
            }
    422
        }
    423
    424
        function log(uint256 p0, bool p1) internal pure {
    425
            bytes32 m0;
    426
            bytes32 m1;
    427
            bytes32 m2;
    428
            /// @solidity memory-safe-assembly
    429
            assembly {
    430
                m0 := mload(0x00)
    431
                m1 := mload(0x20)
    432
                m2 := mload(0x40)
    433
                // Selector of `log(uint256,bool)`.
    434
                mstore(0x00, 0x1c9d7eb3)
    435
                mstore(0x20, p0)
    436
                mstore(0x40, p1)
    437
            }
    438
            _sendLogPayload(0x1c, 0x44);
    439
            /// @solidity memory-safe-assembly
    440
            assembly {
    441
                mstore(0x00, m0)
    442
                mstore(0x20, m1)
    443
                mstore(0x40, m2)
    444
            }
    445
        }
    446
    447
        function log(uint256 p0, uint256 p1) internal pure {
    448
            bytes32 m0;
    449
            bytes32 m1;
    450
            bytes32 m2;
    451
            /// @solidity memory-safe-assembly
    452
            assembly {
    453
                m0 := mload(0x00)
    454
                m1 := mload(0x20)
    455
                m2 := mload(0x40)
    456
                // Selector of `log(uint256,uint256)`.
    457
                mstore(0x00, 0xf666715a)
    458
                mstore(0x20, p0)
    459
                mstore(0x40, p1)
    460
            }
    461
            _sendLogPayload(0x1c, 0x44);
    462
            /// @solidity memory-safe-assembly
    463
            assembly {
    464
                mstore(0x00, m0)
    465
                mstore(0x20, m1)
    466
                mstore(0x40, m2)
    467
            }
    468
        }
    469
    470
        function log(uint256 p0, bytes32 p1) internal pure {
    471
            bytes32 m0;
    472
            bytes32 m1;
    473
            bytes32 m2;
    474
            bytes32 m3;
    475
            bytes32 m4;
    476
            /// @solidity memory-safe-assembly
    477
            assembly {
    478
                function writeString(pos, w) {
    479
                    let length := 0
    480
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    481
                    mstore(pos, length)
    482
                    let shift := sub(256, shl(3, length))
    483
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    484
                }
    485
                m0 := mload(0x00)
    486
                m1 := mload(0x20)
    487
                m2 := mload(0x40)
    488
                m3 := mload(0x60)
    489
                m4 := mload(0x80)
    490
                // Selector of `log(uint256,string)`.
    491
                mstore(0x00, 0x643fd0df)
    492
                mstore(0x20, p0)
    493
                mstore(0x40, 0x40)
    494
                writeString(0x60, p1)
    495
            }
    496
            _sendLogPayload(0x1c, 0x84);
    497
            /// @solidity memory-safe-assembly
    498
            assembly {
    499
                mstore(0x00, m0)
    500
                mstore(0x20, m1)
    501
                mstore(0x40, m2)
    502
                mstore(0x60, m3)
    503
                mstore(0x80, m4)
    504
            }
    505
        }
    506
    507
        function log(bytes32 p0, address p1) internal pure {
    508
            bytes32 m0;
    509
            bytes32 m1;
    510
            bytes32 m2;
    511
            bytes32 m3;
    512
            bytes32 m4;
    513
            /// @solidity memory-safe-assembly
    514
            assembly {
    515
                function writeString(pos, w) {
    516
                    let length := 0
    517
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    518
                    mstore(pos, length)
    519
                    let shift := sub(256, shl(3, length))
    520
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    521
                }
    522
                m0 := mload(0x00)
    523
                m1 := mload(0x20)
    524
                m2 := mload(0x40)
    525
                m3 := mload(0x60)
    526
                m4 := mload(0x80)
    527
                // Selector of `log(string,address)`.
    528
                mstore(0x00, 0x319af333)
    529
                mstore(0x20, 0x40)
    530
                mstore(0x40, p1)
    531
                writeString(0x60, p0)
    532
            }
    533
            _sendLogPayload(0x1c, 0x84);
    534
            /// @solidity memory-safe-assembly
    535
            assembly {
    536
                mstore(0x00, m0)
    537
                mstore(0x20, m1)
    538
                mstore(0x40, m2)
    539
                mstore(0x60, m3)
    540
                mstore(0x80, m4)
    541
            }
    542
        }
    543
    544
        function log(bytes32 p0, bool p1) internal pure {
    545
            bytes32 m0;
    546
            bytes32 m1;
    547
            bytes32 m2;
    548
            bytes32 m3;
    549
            bytes32 m4;
    550
            /// @solidity memory-safe-assembly
    551
            assembly {
    552
                function writeString(pos, w) {
    553
                    let length := 0
    554
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    555
                    mstore(pos, length)
    556
                    let shift := sub(256, shl(3, length))
    557
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    558
                }
    559
                m0 := mload(0x00)
    560
                m1 := mload(0x20)
    561
                m2 := mload(0x40)
    562
                m3 := mload(0x60)
    563
                m4 := mload(0x80)
    564
                // Selector of `log(string,bool)`.
    565
                mstore(0x00, 0xc3b55635)
    566
                mstore(0x20, 0x40)
    567
                mstore(0x40, p1)
    568
                writeString(0x60, p0)
    569
            }
    570
            _sendLogPayload(0x1c, 0x84);
    571
            /// @solidity memory-safe-assembly
    572
            assembly {
    573
                mstore(0x00, m0)
    574
                mstore(0x20, m1)
    575
                mstore(0x40, m2)
    576
                mstore(0x60, m3)
    577
                mstore(0x80, m4)
    578
            }
    579
        }
    580
    581
        function log(bytes32 p0, uint256 p1) internal pure {
    582
            bytes32 m0;
    583
            bytes32 m1;
    584
            bytes32 m2;
    585
            bytes32 m3;
    586
            bytes32 m4;
    587
            /// @solidity memory-safe-assembly
    588
            assembly {
    589
                function writeString(pos, w) {
    590
                    let length := 0
    591
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    592
                    mstore(pos, length)
    593
                    let shift := sub(256, shl(3, length))
    594
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    595
                }
    596
                m0 := mload(0x00)
    597
                m1 := mload(0x20)
    598
                m2 := mload(0x40)
    599
                m3 := mload(0x60)
    600
                m4 := mload(0x80)
    601
                // Selector of `log(string,uint256)`.
    602
                mstore(0x00, 0xb60e72cc)
    603
                mstore(0x20, 0x40)
    604
                mstore(0x40, p1)
    605
                writeString(0x60, p0)
    606
            }
    607
            _sendLogPayload(0x1c, 0x84);
    608
            /// @solidity memory-safe-assembly
    609
            assembly {
    610
                mstore(0x00, m0)
    611
                mstore(0x20, m1)
    612
                mstore(0x40, m2)
    613
                mstore(0x60, m3)
    614
                mstore(0x80, m4)
    615
            }
    616
        }
    617
    618
        function log(bytes32 p0, bytes32 p1) internal pure {
    619
            bytes32 m0;
    620
            bytes32 m1;
    621
            bytes32 m2;
    622
            bytes32 m3;
    623
            bytes32 m4;
    624
            bytes32 m5;
    625
            bytes32 m6;
    626
            /// @solidity memory-safe-assembly
    627
            assembly {
    628
                function writeString(pos, w) {
    629
                    let length := 0
    630
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    631
                    mstore(pos, length)
    632
                    let shift := sub(256, shl(3, length))
    633
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    634
                }
    635
                m0 := mload(0x00)
    636
                m1 := mload(0x20)
    637
                m2 := mload(0x40)
    638
                m3 := mload(0x60)
    639
                m4 := mload(0x80)
    640
                m5 := mload(0xa0)
    641
                m6 := mload(0xc0)
    642
                // Selector of `log(string,string)`.
    643
                mstore(0x00, 0x4b5c4277)
    644
                mstore(0x20, 0x40)
    645
                mstore(0x40, 0x80)
    646
                writeString(0x60, p0)
    647
                writeString(0xa0, p1)
    648
            }
    649
            _sendLogPayload(0x1c, 0xc4);
    650
            /// @solidity memory-safe-assembly
    651
            assembly {
    652
                mstore(0x00, m0)
    653
                mstore(0x20, m1)
    654
                mstore(0x40, m2)
    655
                mstore(0x60, m3)
    656
                mstore(0x80, m4)
    657
                mstore(0xa0, m5)
    658
                mstore(0xc0, m6)
    659
            }
    660
        }
    661
    662
        function log(address p0, address p1, address p2) internal pure {
    663
            bytes32 m0;
    664
            bytes32 m1;
    665
            bytes32 m2;
    666
            bytes32 m3;
    667
            /// @solidity memory-safe-assembly
    668
            assembly {
    669
                m0 := mload(0x00)
    670
                m1 := mload(0x20)
    671
                m2 := mload(0x40)
    672
                m3 := mload(0x60)
    673
                // Selector of `log(address,address,address)`.
    674
                mstore(0x00, 0x018c84c2)
    675
                mstore(0x20, p0)
    676
                mstore(0x40, p1)
    677
                mstore(0x60, p2)
    678
            }
    679
            _sendLogPayload(0x1c, 0x64);
    680
            /// @solidity memory-safe-assembly
    681
            assembly {
    682
                mstore(0x00, m0)
    683
                mstore(0x20, m1)
    684
                mstore(0x40, m2)
    685
                mstore(0x60, m3)
    686
            }
    687
        }
    688
    689
        function log(address p0, address p1, bool p2) internal pure {
    690
            bytes32 m0;
    691
            bytes32 m1;
    692
            bytes32 m2;
    693
            bytes32 m3;
    694
            /// @solidity memory-safe-assembly
    695
            assembly {
    696
                m0 := mload(0x00)
    697
                m1 := mload(0x20)
    698
                m2 := mload(0x40)
    699
                m3 := mload(0x60)
    700
                // Selector of `log(address,address,bool)`.
    701
                mstore(0x00, 0xf2a66286)
    702
                mstore(0x20, p0)
    703
                mstore(0x40, p1)
    704
                mstore(0x60, p2)
    705
            }
    706
            _sendLogPayload(0x1c, 0x64);
    707
            /// @solidity memory-safe-assembly
    708
            assembly {
    709
                mstore(0x00, m0)
    710
                mstore(0x20, m1)
    711
                mstore(0x40, m2)
    712
                mstore(0x60, m3)
    713
            }
    714
        }
    715
    716
        function log(address p0, address p1, uint256 p2) internal pure {
    717
            bytes32 m0;
    718
            bytes32 m1;
    719
            bytes32 m2;
    720
            bytes32 m3;
    721
            /// @solidity memory-safe-assembly
    722
            assembly {
    723
                m0 := mload(0x00)
    724
                m1 := mload(0x20)
    725
                m2 := mload(0x40)
    726
                m3 := mload(0x60)
    727
                // Selector of `log(address,address,uint256)`.
    728
                mstore(0x00, 0x17fe6185)
    729
                mstore(0x20, p0)
    730
                mstore(0x40, p1)
    731
                mstore(0x60, p2)
    732
            }
    733
            _sendLogPayload(0x1c, 0x64);
    734
            /// @solidity memory-safe-assembly
    735
            assembly {
    736
                mstore(0x00, m0)
    737
                mstore(0x20, m1)
    738
                mstore(0x40, m2)
    739
                mstore(0x60, m3)
    740
            }
    741
        }
    742
    743
        function log(address p0, address p1, bytes32 p2) internal pure {
    744
            bytes32 m0;
    745
            bytes32 m1;
    746
            bytes32 m2;
    747
            bytes32 m3;
    748
            bytes32 m4;
    749
            bytes32 m5;
    750
            /// @solidity memory-safe-assembly
    751
            assembly {
    752
                function writeString(pos, w) {
    753
                    let length := 0
    754
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    755
                    mstore(pos, length)
    756
                    let shift := sub(256, shl(3, length))
    757
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    758
                }
    759
                m0 := mload(0x00)
    760
                m1 := mload(0x20)
    761
                m2 := mload(0x40)
    762
                m3 := mload(0x60)
    763
                m4 := mload(0x80)
    764
                m5 := mload(0xa0)
    765
                // Selector of `log(address,address,string)`.
    766
                mstore(0x00, 0x007150be)
    767
                mstore(0x20, p0)
    768
                mstore(0x40, p1)
    769
                mstore(0x60, 0x60)
    770
                writeString(0x80, p2)
    771
            }
    772
            _sendLogPayload(0x1c, 0xa4);
    773
            /// @solidity memory-safe-assembly
    774
            assembly {
    775
                mstore(0x00, m0)
    776
                mstore(0x20, m1)
    777
                mstore(0x40, m2)
    778
                mstore(0x60, m3)
    779
                mstore(0x80, m4)
    780
                mstore(0xa0, m5)
    781
            }
    782
        }
    783
    784
        function log(address p0, bool p1, address p2) internal pure {
    785
            bytes32 m0;
    786
            bytes32 m1;
    787
            bytes32 m2;
    788
            bytes32 m3;
    789
            /// @solidity memory-safe-assembly
    790
            assembly {
    791
                m0 := mload(0x00)
    792
                m1 := mload(0x20)
    793
                m2 := mload(0x40)
    794
                m3 := mload(0x60)
    795
                // Selector of `log(address,bool,address)`.
    796
                mstore(0x00, 0xf11699ed)
    797
                mstore(0x20, p0)
    798
                mstore(0x40, p1)
    799
                mstore(0x60, p2)
    800
            }
    801
            _sendLogPayload(0x1c, 0x64);
    802
            /// @solidity memory-safe-assembly
    803
            assembly {
    804
                mstore(0x00, m0)
    805
                mstore(0x20, m1)
    806
                mstore(0x40, m2)
    807
                mstore(0x60, m3)
    808
            }
    809
        }
    810
    811
        function log(address p0, bool p1, bool p2) internal pure {
    812
            bytes32 m0;
    813
            bytes32 m1;
    814
            bytes32 m2;
    815
            bytes32 m3;
    816
            /// @solidity memory-safe-assembly
    817
            assembly {
    818
                m0 := mload(0x00)
    819
                m1 := mload(0x20)
    820
                m2 := mload(0x40)
    821
                m3 := mload(0x60)
    822
                // Selector of `log(address,bool,bool)`.
    823
                mstore(0x00, 0xeb830c92)
    824
                mstore(0x20, p0)
    825
                mstore(0x40, p1)
    826
                mstore(0x60, p2)
    827
            }
    828
            _sendLogPayload(0x1c, 0x64);
    829
            /// @solidity memory-safe-assembly
    830
            assembly {
    831
                mstore(0x00, m0)
    832
                mstore(0x20, m1)
    833
                mstore(0x40, m2)
    834
                mstore(0x60, m3)
    835
            }
    836
        }
    837
    838
        function log(address p0, bool p1, uint256 p2) internal pure {
    839
            bytes32 m0;
    840
            bytes32 m1;
    841
            bytes32 m2;
    842
            bytes32 m3;
    843
            /// @solidity memory-safe-assembly
    844
            assembly {
    845
                m0 := mload(0x00)
    846
                m1 := mload(0x20)
    847
                m2 := mload(0x40)
    848
                m3 := mload(0x60)
    849
                // Selector of `log(address,bool,uint256)`.
    850
                mstore(0x00, 0x9c4f99fb)
    851
                mstore(0x20, p0)
    852
                mstore(0x40, p1)
    853
                mstore(0x60, p2)
    854
            }
    855
            _sendLogPayload(0x1c, 0x64);
    856
            /// @solidity memory-safe-assembly
    857
            assembly {
    858
                mstore(0x00, m0)
    859
                mstore(0x20, m1)
    860
                mstore(0x40, m2)
    861
                mstore(0x60, m3)
    862
            }
    863
        }
    864
    865
        function log(address p0, bool p1, bytes32 p2) internal pure {
    866
            bytes32 m0;
    867
            bytes32 m1;
    868
            bytes32 m2;
    869
            bytes32 m3;
    870
            bytes32 m4;
    871
            bytes32 m5;
    872
            /// @solidity memory-safe-assembly
    873
            assembly {
    874
                function writeString(pos, w) {
    875
                    let length := 0
    876
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    877
                    mstore(pos, length)
    878
                    let shift := sub(256, shl(3, length))
    879
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    880
                }
    881
                m0 := mload(0x00)
    882
                m1 := mload(0x20)
    883
                m2 := mload(0x40)
    884
                m3 := mload(0x60)
    885
                m4 := mload(0x80)
    886
                m5 := mload(0xa0)
    887
                // Selector of `log(address,bool,string)`.
    888
                mstore(0x00, 0x212255cc)
    889
                mstore(0x20, p0)
    890
                mstore(0x40, p1)
    891
                mstore(0x60, 0x60)
    892
                writeString(0x80, p2)
    893
            }
    894
            _sendLogPayload(0x1c, 0xa4);
    895
            /// @solidity memory-safe-assembly
    896
            assembly {
    897
                mstore(0x00, m0)
    898
                mstore(0x20, m1)
    899
                mstore(0x40, m2)
    900
                mstore(0x60, m3)
    901
                mstore(0x80, m4)
    902
                mstore(0xa0, m5)
    903
            }
    904
        }
    905
    906
        function log(address p0, uint256 p1, address p2) internal pure {
    907
            bytes32 m0;
    908
            bytes32 m1;
    909
            bytes32 m2;
    910
            bytes32 m3;
    911
            /// @solidity memory-safe-assembly
    912
            assembly {
    913
                m0 := mload(0x00)
    914
                m1 := mload(0x20)
    915
                m2 := mload(0x40)
    916
                m3 := mload(0x60)
    917
                // Selector of `log(address,uint256,address)`.
    918
                mstore(0x00, 0x7bc0d848)
    919
                mstore(0x20, p0)
    920
                mstore(0x40, p1)
    921
                mstore(0x60, p2)
    922
            }
    923
            _sendLogPayload(0x1c, 0x64);
    924
            /// @solidity memory-safe-assembly
    925
            assembly {
    926
                mstore(0x00, m0)
    927
                mstore(0x20, m1)
    928
                mstore(0x40, m2)
    929
                mstore(0x60, m3)
    930
            }
    931
        }
    932
    933
        function log(address p0, uint256 p1, bool p2) internal pure {
    934
            bytes32 m0;
    935
            bytes32 m1;
    936
            bytes32 m2;
    937
            bytes32 m3;
    938
            /// @solidity memory-safe-assembly
    939
            assembly {
    940
                m0 := mload(0x00)
    941
                m1 := mload(0x20)
    942
                m2 := mload(0x40)
    943
                m3 := mload(0x60)
    944
                // Selector of `log(address,uint256,bool)`.
    945
                mstore(0x00, 0x678209a8)
    946
                mstore(0x20, p0)
    947
                mstore(0x40, p1)
    948
                mstore(0x60, p2)
    949
            }
    950
            _sendLogPayload(0x1c, 0x64);
    951
            /// @solidity memory-safe-assembly
    952
            assembly {
    953
                mstore(0x00, m0)
    954
                mstore(0x20, m1)
    955
                mstore(0x40, m2)
    956
                mstore(0x60, m3)
    957
            }
    958
        }
    959
    960
        function log(address p0, uint256 p1, uint256 p2) internal pure {
    961
            bytes32 m0;
    962
            bytes32 m1;
    963
            bytes32 m2;
    964
            bytes32 m3;
    965
            /// @solidity memory-safe-assembly
    966
            assembly {
    967
                m0 := mload(0x00)
    968
                m1 := mload(0x20)
    969
                m2 := mload(0x40)
    970
                m3 := mload(0x60)
    971
                // Selector of `log(address,uint256,uint256)`.
    972
                mstore(0x00, 0xb69bcaf6)
    973
                mstore(0x20, p0)
    974
                mstore(0x40, p1)
    975
                mstore(0x60, p2)
    976
            }
    977
            _sendLogPayload(0x1c, 0x64);
    978
            /// @solidity memory-safe-assembly
    979
            assembly {
    980
                mstore(0x00, m0)
    981
                mstore(0x20, m1)
    982
                mstore(0x40, m2)
    983
                mstore(0x60, m3)
    984
            }
    985
        }
    986
    987
        function log(address p0, uint256 p1, bytes32 p2) internal pure {
    988
            bytes32 m0;
    989
            bytes32 m1;
    990
            bytes32 m2;
    991
            bytes32 m3;
    992
            bytes32 m4;
    993
            bytes32 m5;
    994
            /// @solidity memory-safe-assembly
    995
            assembly {
    996
                function writeString(pos, w) {
    997
                    let length := 0
    998
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    999
                    mstore(pos, length)
    1000
                    let shift := sub(256, shl(3, length))
    1001
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    1002
                }
    1003
                m0 := mload(0x00)
    1004
                m1 := mload(0x20)
    1005
                m2 := mload(0x40)
    1006
                m3 := mload(0x60)
    1007
                m4 := mload(0x80)
    1008
                m5 := mload(0xa0)
    1009
                // Selector of `log(address,uint256,string)`.
    1010
                mstore(0x00, 0xa1f2e8aa)
    1011
                mstore(0x20, p0)
    1012
                mstore(0x40, p1)
    1013
                mstore(0x60, 0x60)
    1014
                writeString(0x80, p2)
    1015
            }
    1016
            _sendLogPayload(0x1c, 0xa4);
    1017
            /// @solidity memory-safe-assembly
    1018
            assembly {
    1019
                mstore(0x00, m0)
    1020
                mstore(0x20, m1)
    1021
                mstore(0x40, m2)
    1022
                mstore(0x60, m3)
    1023
                mstore(0x80, m4)
    1024
                mstore(0xa0, m5)
    1025
            }
    1026
        }
    1027
    1028
        function log(address p0, bytes32 p1, address p2) internal pure {
    1029
            bytes32 m0;
    1030
            bytes32 m1;
    1031
            bytes32 m2;
    1032
            bytes32 m3;
    1033
            bytes32 m4;
    1034
            bytes32 m5;
    1035
            /// @solidity memory-safe-assembly
    1036
            assembly {
    1037
                function writeString(pos, w) {
    1038
                    let length := 0
    1039
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    1040
                    mstore(pos, length)
    1041
                    let shift := sub(256, shl(3, length))
    1042
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    1043
                }
    1044
                m0 := mload(0x00)
    1045
                m1 := mload(0x20)
    1046
                m2 := mload(0x40)
    1047
                m3 := mload(0x60)
    1048
                m4 := mload(0x80)
    1049
                m5 := mload(0xa0)
    1050
                // Selector of `log(address,string,address)`.
    1051
                mstore(0x00, 0xf08744e8)
    1052
                mstore(0x20, p0)
    1053
                mstore(0x40, 0x60)
    1054
                mstore(0x60, p2)
    1055
                writeString(0x80, p1)
    1056
            }
    1057
            _sendLogPayload(0x1c, 0xa4);
    1058
            /// @solidity memory-safe-assembly
    1059
            assembly {
    1060
                mstore(0x00, m0)
    1061
                mstore(0x20, m1)
    1062
                mstore(0x40, m2)
    1063
                mstore(0x60, m3)
    1064
                mstore(0x80, m4)
    1065
                mstore(0xa0, m5)
    1066
            }
    1067
        }
    1068
    1069
        function log(address p0, bytes32 p1, bool p2) internal pure {
    1070
            bytes32 m0;
    1071
            bytes32 m1;
    1072
            bytes32 m2;
    1073
            bytes32 m3;
    1074
            bytes32 m4;
    1075
            bytes32 m5;
    1076
            /// @solidity memory-safe-assembly
    1077
            assembly {
    1078
                function writeString(pos, w) {
    1079
                    let length := 0
    1080
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    1081
                    mstore(pos, length)
    1082
                    let shift := sub(256, shl(3, length))
    1083
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    1084
                }
    1085
                m0 := mload(0x00)
    1086
                m1 := mload(0x20)
    1087
                m2 := mload(0x40)
    1088
                m3 := mload(0x60)
    1089
                m4 := mload(0x80)
    1090
                m5 := mload(0xa0)
    1091
                // Selector of `log(address,string,bool)`.
    1092
                mstore(0x00, 0xcf020fb1)
    1093
                mstore(0x20, p0)
    1094
                mstore(0x40, 0x60)
    1095
                mstore(0x60, p2)
    1096
                writeString(0x80, p1)
    1097
            }
    1098
            _sendLogPayload(0x1c, 0xa4);
    1099
            /// @solidity memory-safe-assembly
    1100
            assembly {
    1101
                mstore(0x00, m0)
    1102
                mstore(0x20, m1)
    1103
                mstore(0x40, m2)
    1104
                mstore(0x60, m3)
    1105
                mstore(0x80, m4)
    1106
                mstore(0xa0, m5)
    1107
            }
    1108
        }
    1109
    1110
        function log(address p0, bytes32 p1, uint256 p2) internal pure {
    1111
            bytes32 m0;
    1112
            bytes32 m1;
    1113
            bytes32 m2;
    1114
            bytes32 m3;
    1115
            bytes32 m4;
    1116
            bytes32 m5;
    1117
            /// @solidity memory-safe-assembly
    1118
            assembly {
    1119
                function writeString(pos, w) {
    1120
                    let length := 0
    1121
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    1122
                    mstore(pos, length)
    1123
                    let shift := sub(256, shl(3, length))
    1124
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    1125
                }
    1126
                m0 := mload(0x00)
    1127
                m1 := mload(0x20)
    1128
                m2 := mload(0x40)
    1129
                m3 := mload(0x60)
    1130
                m4 := mload(0x80)
    1131
                m5 := mload(0xa0)
    1132
                // Selector of `log(address,string,uint256)`.
    1133
                mstore(0x00, 0x67dd6ff1)
    1134
                mstore(0x20, p0)
    1135
                mstore(0x40, 0x60)
    1136
                mstore(0x60, p2)
    1137
                writeString(0x80, p1)
    1138
            }
    1139
            _sendLogPayload(0x1c, 0xa4);
    1140
            /// @solidity memory-safe-assembly
    1141
            assembly {
    1142
                mstore(0x00, m0)
    1143
                mstore(0x20, m1)
    1144
                mstore(0x40, m2)
    1145
                mstore(0x60, m3)
    1146
                mstore(0x80, m4)
    1147
                mstore(0xa0, m5)
    1148
            }
    1149
        }
    1150
    1151
        function log(address p0, bytes32 p1, bytes32 p2) internal pure {
    1152
            bytes32 m0;
    1153
            bytes32 m1;
    1154
            bytes32 m2;
    1155
            bytes32 m3;
    1156
            bytes32 m4;
    1157
            bytes32 m5;
    1158
            bytes32 m6;
    1159
            bytes32 m7;
    1160
            /// @solidity memory-safe-assembly
    1161
            assembly {
    1162
                function writeString(pos, w) {
    1163
                    let length := 0
    1164
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    1165
                    mstore(pos, length)
    1166
                    let shift := sub(256, shl(3, length))
    1167
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    1168
                }
    1169
                m0 := mload(0x00)
    1170
                m1 := mload(0x20)
    1171
                m2 := mload(0x40)
    1172
                m3 := mload(0x60)
    1173
                m4 := mload(0x80)
    1174
                m5 := mload(0xa0)
    1175
                m6 := mload(0xc0)
    1176
                m7 := mload(0xe0)
    1177
                // Selector of `log(address,string,string)`.
    1178
                mstore(0x00, 0xfb772265)
    1179
                mstore(0x20, p0)
    1180
                mstore(0x40, 0x60)
    1181
                mstore(0x60, 0xa0)
    1182
                writeString(0x80, p1)
    1183
                writeString(0xc0, p2)
    1184
            }
    1185
            _sendLogPayload(0x1c, 0xe4);
    1186
            /// @solidity memory-safe-assembly
    1187
            assembly {
    1188
                mstore(0x00, m0)
    1189
                mstore(0x20, m1)
    1190
                mstore(0x40, m2)
    1191
                mstore(0x60, m3)
    1192
                mstore(0x80, m4)
    1193
                mstore(0xa0, m5)
    1194
                mstore(0xc0, m6)
    1195
                mstore(0xe0, m7)
    1196
            }
    1197
        }
    1198
    1199
        function log(bool p0, address p1, address p2) internal pure {
    1200
            bytes32 m0;
    1201
            bytes32 m1;
    1202
            bytes32 m2;
    1203
            bytes32 m3;
    1204
            /// @solidity memory-safe-assembly
    1205
            assembly {
    1206
                m0 := mload(0x00)
    1207
                m1 := mload(0x20)
    1208
                m2 := mload(0x40)
    1209
                m3 := mload(0x60)
    1210
                // Selector of `log(bool,address,address)`.
    1211
                mstore(0x00, 0xd2763667)
    1212
                mstore(0x20, p0)
    1213
                mstore(0x40, p1)
    1214
                mstore(0x60, p2)
    1215
            }
    1216
            _sendLogPayload(0x1c, 0x64);
    1217
            /// @solidity memory-safe-assembly
    1218
            assembly {
    1219
                mstore(0x00, m0)
    1220
                mstore(0x20, m1)
    1221
                mstore(0x40, m2)
    1222
                mstore(0x60, m3)
    1223
            }
    1224
        }
    1225
    1226
        function log(bool p0, address p1, bool p2) internal pure {
    1227
            bytes32 m0;
    1228
            bytes32 m1;
    1229
            bytes32 m2;
    1230
            bytes32 m3;
    1231
            /// @solidity memory-safe-assembly
    1232
            assembly {
    1233
                m0 := mload(0x00)
    1234
                m1 := mload(0x20)
    1235
                m2 := mload(0x40)
    1236
                m3 := mload(0x60)
    1237
                // Selector of `log(bool,address,bool)`.
    1238
                mstore(0x00, 0x18c9c746)
    1239
                mstore(0x20, p0)
    1240
                mstore(0x40, p1)
    1241
                mstore(0x60, p2)
    1242
            }
    1243
            _sendLogPayload(0x1c, 0x64);
    1244
            /// @solidity memory-safe-assembly
    1245
            assembly {
    1246
                mstore(0x00, m0)
    1247
                mstore(0x20, m1)
    1248
                mstore(0x40, m2)
    1249
                mstore(0x60, m3)
    1250
            }
    1251
        }
    1252
    1253
        function log(bool p0, address p1, uint256 p2) internal pure {
    1254
            bytes32 m0;
    1255
            bytes32 m1;
    1256
            bytes32 m2;
    1257
            bytes32 m3;
    1258
            /// @solidity memory-safe-assembly
    1259
            assembly {
    1260
                m0 := mload(0x00)
    1261
                m1 := mload(0x20)
    1262
                m2 := mload(0x40)
    1263
                m3 := mload(0x60)
    1264
                // Selector of `log(bool,address,uint256)`.
    1265
                mstore(0x00, 0x5f7b9afb)
    1266
                mstore(0x20, p0)
    1267
                mstore(0x40, p1)
    1268
                mstore(0x60, p2)
    1269
            }
    1270
            _sendLogPayload(0x1c, 0x64);
    1271
            /// @solidity memory-safe-assembly
    1272
            assembly {
    1273
                mstore(0x00, m0)
    1274
                mstore(0x20, m1)
    1275
                mstore(0x40, m2)
    1276
                mstore(0x60, m3)
    1277
            }
    1278
        }
    1279
    1280
        function log(bool p0, address p1, bytes32 p2) internal pure {
    1281
            bytes32 m0;
    1282
            bytes32 m1;
    1283
            bytes32 m2;
    1284
            bytes32 m3;
    1285
            bytes32 m4;
    1286
            bytes32 m5;
    1287
            /// @solidity memory-safe-assembly
    1288
            assembly {
    1289
                function writeString(pos, w) {
    1290
                    let length := 0
    1291
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    1292
                    mstore(pos, length)
    1293
                    let shift := sub(256, shl(3, length))
    1294
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    1295
                }
    1296
                m0 := mload(0x00)
    1297
                m1 := mload(0x20)
    1298
                m2 := mload(0x40)
    1299
                m3 := mload(0x60)
    1300
                m4 := mload(0x80)
    1301
                m5 := mload(0xa0)
    1302
                // Selector of `log(bool,address,string)`.
    1303
                mstore(0x00, 0xde9a9270)
    1304
                mstore(0x20, p0)
    1305
                mstore(0x40, p1)
    1306
                mstore(0x60, 0x60)
    1307
                writeString(0x80, p2)
    1308
            }
    1309
            _sendLogPayload(0x1c, 0xa4);
    1310
            /// @solidity memory-safe-assembly
    1311
            assembly {
    1312
                mstore(0x00, m0)
    1313
                mstore(0x20, m1)
    1314
                mstore(0x40, m2)
    1315
                mstore(0x60, m3)
    1316
                mstore(0x80, m4)
    1317
                mstore(0xa0, m5)
    1318
            }
    1319
        }
    1320
    1321
        function log(bool p0, bool p1, address p2) internal pure {
    1322
            bytes32 m0;
    1323
            bytes32 m1;
    1324
            bytes32 m2;
    1325
            bytes32 m3;
    1326
            /// @solidity memory-safe-assembly
    1327
            assembly {
    1328
                m0 := mload(0x00)
    1329
                m1 := mload(0x20)
    1330
                m2 := mload(0x40)
    1331
                m3 := mload(0x60)
    1332
                // Selector of `log(bool,bool,address)`.
    1333
                mstore(0x00, 0x1078f68d)
    1334
                mstore(0x20, p0)
    1335
                mstore(0x40, p1)
    1336
                mstore(0x60, p2)
    1337
            }
    1338
            _sendLogPayload(0x1c, 0x64);
    1339
            /// @solidity memory-safe-assembly
    1340
            assembly {
    1341
                mstore(0x00, m0)
    1342
                mstore(0x20, m1)
    1343
                mstore(0x40, m2)
    1344
                mstore(0x60, m3)
    1345
            }
    1346
        }
    1347
    1348
        function log(bool p0, bool p1, bool p2) internal pure {
    1349
            bytes32 m0;
    1350
            bytes32 m1;
    1351
            bytes32 m2;
    1352
            bytes32 m3;
    1353
            /// @solidity memory-safe-assembly
    1354
            assembly {
    1355
                m0 := mload(0x00)
    1356
                m1 := mload(0x20)
    1357
                m2 := mload(0x40)
    1358
                m3 := mload(0x60)
    1359
                // Selector of `log(bool,bool,bool)`.
    1360
                mstore(0x00, 0x50709698)
    1361
                mstore(0x20, p0)
    1362
                mstore(0x40, p1)
    1363
                mstore(0x60, p2)
    1364
            }
    1365
            _sendLogPayload(0x1c, 0x64);
    1366
            /// @solidity memory-safe-assembly
    1367
            assembly {
    1368
                mstore(0x00, m0)
    1369
                mstore(0x20, m1)
    1370
                mstore(0x40, m2)
    1371
                mstore(0x60, m3)
    1372
            }
    1373
        }
    1374
    1375
        function log(bool p0, bool p1, uint256 p2) internal pure {
    1376
            bytes32 m0;
    1377
            bytes32 m1;
    1378
            bytes32 m2;
    1379
            bytes32 m3;
    1380
            /// @solidity memory-safe-assembly
    1381
            assembly {
    1382
                m0 := mload(0x00)
    1383
                m1 := mload(0x20)
    1384
                m2 := mload(0x40)
    1385
                m3 := mload(0x60)
    1386
                // Selector of `log(bool,bool,uint256)`.
    1387
                mstore(0x00, 0x12f21602)
    1388
                mstore(0x20, p0)
    1389
                mstore(0x40, p1)
    1390
                mstore(0x60, p2)
    1391
            }
    1392
            _sendLogPayload(0x1c, 0x64);
    1393
            /// @solidity memory-safe-assembly
    1394
            assembly {
    1395
                mstore(0x00, m0)
    1396
                mstore(0x20, m1)
    1397
                mstore(0x40, m2)
    1398
                mstore(0x60, m3)
    1399
            }
    1400
        }
    1401
    1402
        function log(bool p0, bool p1, bytes32 p2) internal pure {
    1403
            bytes32 m0;
    1404
            bytes32 m1;
    1405
            bytes32 m2;
    1406
            bytes32 m3;
    1407
            bytes32 m4;
    1408
            bytes32 m5;
    1409
            /// @solidity memory-safe-assembly
    1410
            assembly {
    1411
                function writeString(pos, w) {
    1412
                    let length := 0
    1413
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    1414
                    mstore(pos, length)
    1415
                    let shift := sub(256, shl(3, length))
    1416
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    1417
                }
    1418
                m0 := mload(0x00)
    1419
                m1 := mload(0x20)
    1420
                m2 := mload(0x40)
    1421
                m3 := mload(0x60)
    1422
                m4 := mload(0x80)
    1423
                m5 := mload(0xa0)
    1424
                // Selector of `log(bool,bool,string)`.
    1425
                mstore(0x00, 0x2555fa46)
    1426
                mstore(0x20, p0)
    1427
                mstore(0x40, p1)
    1428
                mstore(0x60, 0x60)
    1429
                writeString(0x80, p2)
    1430
            }
    1431
            _sendLogPayload(0x1c, 0xa4);
    1432
            /// @solidity memory-safe-assembly
    1433
            assembly {
    1434
                mstore(0x00, m0)
    1435
                mstore(0x20, m1)
    1436
                mstore(0x40, m2)
    1437
                mstore(0x60, m3)
    1438
                mstore(0x80, m4)
    1439
                mstore(0xa0, m5)
    1440
            }
    1441
        }
    1442
    1443
        function log(bool p0, uint256 p1, address p2) internal pure {
    1444
            bytes32 m0;
    1445
            bytes32 m1;
    1446
            bytes32 m2;
    1447
            bytes32 m3;
    1448
            /// @solidity memory-safe-assembly
    1449
            assembly {
    1450
                m0 := mload(0x00)
    1451
                m1 := mload(0x20)
    1452
                m2 := mload(0x40)
    1453
                m3 := mload(0x60)
    1454
                // Selector of `log(bool,uint256,address)`.
    1455
                mstore(0x00, 0x088ef9d2)
    1456
                mstore(0x20, p0)
    1457
                mstore(0x40, p1)
    1458
                mstore(0x60, p2)
    1459
            }
    1460
            _sendLogPayload(0x1c, 0x64);
    1461
            /// @solidity memory-safe-assembly
    1462
            assembly {
    1463
                mstore(0x00, m0)
    1464
                mstore(0x20, m1)
    1465
                mstore(0x40, m2)
    1466
                mstore(0x60, m3)
    1467
            }
    1468
        }
    1469
    1470
        function log(bool p0, uint256 p1, bool p2) internal pure {
    1471
            bytes32 m0;
    1472
            bytes32 m1;
    1473
            bytes32 m2;
    1474
            bytes32 m3;
    1475
            /// @solidity memory-safe-assembly
    1476
            assembly {
    1477
                m0 := mload(0x00)
    1478
                m1 := mload(0x20)
    1479
                m2 := mload(0x40)
    1480
                m3 := mload(0x60)
    1481
                // Selector of `log(bool,uint256,bool)`.
    1482
                mstore(0x00, 0xe8defba9)
    1483
                mstore(0x20, p0)
    1484
                mstore(0x40, p1)
    1485
                mstore(0x60, p2)
    1486
            }
    1487
            _sendLogPayload(0x1c, 0x64);
    1488
            /// @solidity memory-safe-assembly
    1489
            assembly {
    1490
                mstore(0x00, m0)
    1491
                mstore(0x20, m1)
    1492
                mstore(0x40, m2)
    1493
                mstore(0x60, m3)
    1494
            }
    1495
        }
    1496
    1497
        function log(bool p0, uint256 p1, uint256 p2) internal pure {
    1498
            bytes32 m0;
    1499
            bytes32 m1;
    1500
            bytes32 m2;
    1501
            bytes32 m3;
    1502
            /// @solidity memory-safe-assembly
    1503
            assembly {
    1504
                m0 := mload(0x00)
    1505
                m1 := mload(0x20)
    1506
                m2 := mload(0x40)
    1507
                m3 := mload(0x60)
    1508
                // Selector of `log(bool,uint256,uint256)`.
    1509
                mstore(0x00, 0x37103367)
    1510
                mstore(0x20, p0)
    1511
                mstore(0x40, p1)
    1512
                mstore(0x60, p2)
    1513
            }
    1514
            _sendLogPayload(0x1c, 0x64);
    1515
            /// @solidity memory-safe-assembly
    1516
            assembly {
    1517
                mstore(0x00, m0)
    1518
                mstore(0x20, m1)
    1519
                mstore(0x40, m2)
    1520
                mstore(0x60, m3)
    1521
            }
    1522
        }
    1523
    1524
        function log(bool p0, uint256 p1, bytes32 p2) internal pure {
    1525
            bytes32 m0;
    1526
            bytes32 m1;
    1527
            bytes32 m2;
    1528
            bytes32 m3;
    1529
            bytes32 m4;
    1530
            bytes32 m5;
    1531
            /// @solidity memory-safe-assembly
    1532
            assembly {
    1533
                function writeString(pos, w) {
    1534
                    let length := 0
    1535
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    1536
                    mstore(pos, length)
    1537
                    let shift := sub(256, shl(3, length))
    1538
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    1539
                }
    1540
                m0 := mload(0x00)
    1541
                m1 := mload(0x20)
    1542
                m2 := mload(0x40)
    1543
                m3 := mload(0x60)
    1544
                m4 := mload(0x80)
    1545
                m5 := mload(0xa0)
    1546
                // Selector of `log(bool,uint256,string)`.
    1547
                mstore(0x00, 0xc3fc3970)
    1548
                mstore(0x20, p0)
    1549
                mstore(0x40, p1)
    1550
                mstore(0x60, 0x60)
    1551
                writeString(0x80, p2)
    1552
            }
    1553
            _sendLogPayload(0x1c, 0xa4);
    1554
            /// @solidity memory-safe-assembly
    1555
            assembly {
    1556
                mstore(0x00, m0)
    1557
                mstore(0x20, m1)
    1558
                mstore(0x40, m2)
    1559
                mstore(0x60, m3)
    1560
                mstore(0x80, m4)
    1561
                mstore(0xa0, m5)
    1562
            }
    1563
        }
    1564
    1565
        function log(bool p0, bytes32 p1, address p2) internal pure {
    1566
            bytes32 m0;
    1567
            bytes32 m1;
    1568
            bytes32 m2;
    1569
            bytes32 m3;
    1570
            bytes32 m4;
    1571
            bytes32 m5;
    1572
            /// @solidity memory-safe-assembly
    1573
            assembly {
    1574
                function writeString(pos, w) {
    1575
                    let length := 0
    1576
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    1577
                    mstore(pos, length)
    1578
                    let shift := sub(256, shl(3, length))
    1579
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    1580
                }
    1581
                m0 := mload(0x00)
    1582
                m1 := mload(0x20)
    1583
                m2 := mload(0x40)
    1584
                m3 := mload(0x60)
    1585
                m4 := mload(0x80)
    1586
                m5 := mload(0xa0)
    1587
                // Selector of `log(bool,string,address)`.
    1588
                mstore(0x00, 0x9591b953)
    1589
                mstore(0x20, p0)
    1590
                mstore(0x40, 0x60)
    1591
                mstore(0x60, p2)
    1592
                writeString(0x80, p1)
    1593
            }
    1594
            _sendLogPayload(0x1c, 0xa4);
    1595
            /// @solidity memory-safe-assembly
    1596
            assembly {
    1597
                mstore(0x00, m0)
    1598
                mstore(0x20, m1)
    1599
                mstore(0x40, m2)
    1600
                mstore(0x60, m3)
    1601
                mstore(0x80, m4)
    1602
                mstore(0xa0, m5)
    1603
            }
    1604
        }
    1605
    1606
        function log(bool p0, bytes32 p1, bool p2) internal pure {
    1607
            bytes32 m0;
    1608
            bytes32 m1;
    1609
            bytes32 m2;
    1610
            bytes32 m3;
    1611
            bytes32 m4;
    1612
            bytes32 m5;
    1613
            /// @solidity memory-safe-assembly
    1614
            assembly {
    1615
                function writeString(pos, w) {
    1616
                    let length := 0
    1617
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    1618
                    mstore(pos, length)
    1619
                    let shift := sub(256, shl(3, length))
    1620
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    1621
                }
    1622
                m0 := mload(0x00)
    1623
                m1 := mload(0x20)
    1624
                m2 := mload(0x40)
    1625
                m3 := mload(0x60)
    1626
                m4 := mload(0x80)
    1627
                m5 := mload(0xa0)
    1628
                // Selector of `log(bool,string,bool)`.
    1629
                mstore(0x00, 0xdbb4c247)
    1630
                mstore(0x20, p0)
    1631
                mstore(0x40, 0x60)
    1632
                mstore(0x60, p2)
    1633
                writeString(0x80, p1)
    1634
            }
    1635
            _sendLogPayload(0x1c, 0xa4);
    1636
            /// @solidity memory-safe-assembly
    1637
            assembly {
    1638
                mstore(0x00, m0)
    1639
                mstore(0x20, m1)
    1640
                mstore(0x40, m2)
    1641
                mstore(0x60, m3)
    1642
                mstore(0x80, m4)
    1643
                mstore(0xa0, m5)
    1644
            }
    1645
        }
    1646
    1647
        function log(bool p0, bytes32 p1, uint256 p2) internal pure {
    1648
            bytes32 m0;
    1649
            bytes32 m1;
    1650
            bytes32 m2;
    1651
            bytes32 m3;
    1652
            bytes32 m4;
    1653
            bytes32 m5;
    1654
            /// @solidity memory-safe-assembly
    1655
            assembly {
    1656
                function writeString(pos, w) {
    1657
                    let length := 0
    1658
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    1659
                    mstore(pos, length)
    1660
                    let shift := sub(256, shl(3, length))
    1661
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    1662
                }
    1663
                m0 := mload(0x00)
    1664
                m1 := mload(0x20)
    1665
                m2 := mload(0x40)
    1666
                m3 := mload(0x60)
    1667
                m4 := mload(0x80)
    1668
                m5 := mload(0xa0)
    1669
                // Selector of `log(bool,string,uint256)`.
    1670
                mstore(0x00, 0x1093ee11)
    1671
                mstore(0x20, p0)
    1672
                mstore(0x40, 0x60)
    1673
                mstore(0x60, p2)
    1674
                writeString(0x80, p1)
    1675
            }
    1676
            _sendLogPayload(0x1c, 0xa4);
    1677
            /// @solidity memory-safe-assembly
    1678
            assembly {
    1679
                mstore(0x00, m0)
    1680
                mstore(0x20, m1)
    1681
                mstore(0x40, m2)
    1682
                mstore(0x60, m3)
    1683
                mstore(0x80, m4)
    1684
                mstore(0xa0, m5)
    1685
            }
    1686
        }
    1687
    1688
        function log(bool p0, bytes32 p1, bytes32 p2) internal pure {
    1689
            bytes32 m0;
    1690
            bytes32 m1;
    1691
            bytes32 m2;
    1692
            bytes32 m3;
    1693
            bytes32 m4;
    1694
            bytes32 m5;
    1695
            bytes32 m6;
    1696
            bytes32 m7;
    1697
            /// @solidity memory-safe-assembly
    1698
            assembly {
    1699
                function writeString(pos, w) {
    1700
                    let length := 0
    1701
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    1702
                    mstore(pos, length)
    1703
                    let shift := sub(256, shl(3, length))
    1704
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    1705
                }
    1706
                m0 := mload(0x00)
    1707
                m1 := mload(0x20)
    1708
                m2 := mload(0x40)
    1709
                m3 := mload(0x60)
    1710
                m4 := mload(0x80)
    1711
                m5 := mload(0xa0)
    1712
                m6 := mload(0xc0)
    1713
                m7 := mload(0xe0)
    1714
                // Selector of `log(bool,string,string)`.
    1715
                mstore(0x00, 0xb076847f)
    1716
                mstore(0x20, p0)
    1717
                mstore(0x40, 0x60)
    1718
                mstore(0x60, 0xa0)
    1719
                writeString(0x80, p1)
    1720
                writeString(0xc0, p2)
    1721
            }
    1722
            _sendLogPayload(0x1c, 0xe4);
    1723
            /// @solidity memory-safe-assembly
    1724
            assembly {
    1725
                mstore(0x00, m0)
    1726
                mstore(0x20, m1)
    1727
                mstore(0x40, m2)
    1728
                mstore(0x60, m3)
    1729
                mstore(0x80, m4)
    1730
                mstore(0xa0, m5)
    1731
                mstore(0xc0, m6)
    1732
                mstore(0xe0, m7)
    1733
            }
    1734
        }
    1735
    1736
        function log(uint256 p0, address p1, address p2) internal pure {
    1737
            bytes32 m0;
    1738
            bytes32 m1;
    1739
            bytes32 m2;
    1740
            bytes32 m3;
    1741
            /// @solidity memory-safe-assembly
    1742
            assembly {
    1743
                m0 := mload(0x00)
    1744
                m1 := mload(0x20)
    1745
                m2 := mload(0x40)
    1746
                m3 := mload(0x60)
    1747
                // Selector of `log(uint256,address,address)`.
    1748
                mstore(0x00, 0xbcfd9be0)
    1749
                mstore(0x20, p0)
    1750
                mstore(0x40, p1)
    1751
                mstore(0x60, p2)
    1752
            }
    1753
            _sendLogPayload(0x1c, 0x64);
    1754
            /// @solidity memory-safe-assembly
    1755
            assembly {
    1756
                mstore(0x00, m0)
    1757
                mstore(0x20, m1)
    1758
                mstore(0x40, m2)
    1759
                mstore(0x60, m3)
    1760
            }
    1761
        }
    1762
    1763
        function log(uint256 p0, address p1, bool p2) internal pure {
    1764
            bytes32 m0;
    1765
            bytes32 m1;
    1766
            bytes32 m2;
    1767
            bytes32 m3;
    1768
            /// @solidity memory-safe-assembly
    1769
            assembly {
    1770
                m0 := mload(0x00)
    1771
                m1 := mload(0x20)
    1772
                m2 := mload(0x40)
    1773
                m3 := mload(0x60)
    1774
                // Selector of `log(uint256,address,bool)`.
    1775
                mstore(0x00, 0x9b6ec042)
    1776
                mstore(0x20, p0)
    1777
                mstore(0x40, p1)
    1778
                mstore(0x60, p2)
    1779
            }
    1780
            _sendLogPayload(0x1c, 0x64);
    1781
            /// @solidity memory-safe-assembly
    1782
            assembly {
    1783
                mstore(0x00, m0)
    1784
                mstore(0x20, m1)
    1785
                mstore(0x40, m2)
    1786
                mstore(0x60, m3)
    1787
            }
    1788
        }
    1789
    1790
        function log(uint256 p0, address p1, uint256 p2) internal pure {
    1791
            bytes32 m0;
    1792
            bytes32 m1;
    1793
            bytes32 m2;
    1794
            bytes32 m3;
    1795
            /// @solidity memory-safe-assembly
    1796
            assembly {
    1797
                m0 := mload(0x00)
    1798
                m1 := mload(0x20)
    1799
                m2 := mload(0x40)
    1800
                m3 := mload(0x60)
    1801
                // Selector of `log(uint256,address,uint256)`.
    1802
                mstore(0x00, 0x5a9b5ed5)
    1803
                mstore(0x20, p0)
    1804
                mstore(0x40, p1)
    1805
                mstore(0x60, p2)
    1806
            }
    1807
            _sendLogPayload(0x1c, 0x64);
    1808
            /// @solidity memory-safe-assembly
    1809
            assembly {
    1810
                mstore(0x00, m0)
    1811
                mstore(0x20, m1)
    1812
                mstore(0x40, m2)
    1813
                mstore(0x60, m3)
    1814
            }
    1815
        }
    1816
    1817
        function log(uint256 p0, address p1, bytes32 p2) internal pure {
    1818
            bytes32 m0;
    1819
            bytes32 m1;
    1820
            bytes32 m2;
    1821
            bytes32 m3;
    1822
            bytes32 m4;
    1823
            bytes32 m5;
    1824
            /// @solidity memory-safe-assembly
    1825
            assembly {
    1826
                function writeString(pos, w) {
    1827
                    let length := 0
    1828
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    1829
                    mstore(pos, length)
    1830
                    let shift := sub(256, shl(3, length))
    1831
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    1832
                }
    1833
                m0 := mload(0x00)
    1834
                m1 := mload(0x20)
    1835
                m2 := mload(0x40)
    1836
                m3 := mload(0x60)
    1837
                m4 := mload(0x80)
    1838
                m5 := mload(0xa0)
    1839
                // Selector of `log(uint256,address,string)`.
    1840
                mstore(0x00, 0x63cb41f9)
    1841
                mstore(0x20, p0)
    1842
                mstore(0x40, p1)
    1843
                mstore(0x60, 0x60)
    1844
                writeString(0x80, p2)
    1845
            }
    1846
            _sendLogPayload(0x1c, 0xa4);
    1847
            /// @solidity memory-safe-assembly
    1848
            assembly {
    1849
                mstore(0x00, m0)
    1850
                mstore(0x20, m1)
    1851
                mstore(0x40, m2)
    1852
                mstore(0x60, m3)
    1853
                mstore(0x80, m4)
    1854
                mstore(0xa0, m5)
    1855
            }
    1856
        }
    1857
    1858
        function log(uint256 p0, bool p1, address p2) internal pure {
    1859
            bytes32 m0;
    1860
            bytes32 m1;
    1861
            bytes32 m2;
    1862
            bytes32 m3;
    1863
            /// @solidity memory-safe-assembly
    1864
            assembly {
    1865
                m0 := mload(0x00)
    1866
                m1 := mload(0x20)
    1867
                m2 := mload(0x40)
    1868
                m3 := mload(0x60)
    1869
                // Selector of `log(uint256,bool,address)`.
    1870
                mstore(0x00, 0x35085f7b)
    1871
                mstore(0x20, p0)
    1872
                mstore(0x40, p1)
    1873
                mstore(0x60, p2)
    1874
            }
    1875
            _sendLogPayload(0x1c, 0x64);
    1876
            /// @solidity memory-safe-assembly
    1877
            assembly {
    1878
                mstore(0x00, m0)
    1879
                mstore(0x20, m1)
    1880
                mstore(0x40, m2)
    1881
                mstore(0x60, m3)
    1882
            }
    1883
        }
    1884
    1885
        function log(uint256 p0, bool p1, bool p2) internal pure {
    1886
            bytes32 m0;
    1887
            bytes32 m1;
    1888
            bytes32 m2;
    1889
            bytes32 m3;
    1890
            /// @solidity memory-safe-assembly
    1891
            assembly {
    1892
                m0 := mload(0x00)
    1893
                m1 := mload(0x20)
    1894
                m2 := mload(0x40)
    1895
                m3 := mload(0x60)
    1896
                // Selector of `log(uint256,bool,bool)`.
    1897
                mstore(0x00, 0x20718650)
    1898
                mstore(0x20, p0)
    1899
                mstore(0x40, p1)
    1900
                mstore(0x60, p2)
    1901
            }
    1902
            _sendLogPayload(0x1c, 0x64);
    1903
            /// @solidity memory-safe-assembly
    1904
            assembly {
    1905
                mstore(0x00, m0)
    1906
                mstore(0x20, m1)
    1907
                mstore(0x40, m2)
    1908
                mstore(0x60, m3)
    1909
            }
    1910
        }
    1911
    1912
        function log(uint256 p0, bool p1, uint256 p2) internal pure {
    1913
            bytes32 m0;
    1914
            bytes32 m1;
    1915
            bytes32 m2;
    1916
            bytes32 m3;
    1917
            /// @solidity memory-safe-assembly
    1918
            assembly {
    1919
                m0 := mload(0x00)
    1920
                m1 := mload(0x20)
    1921
                m2 := mload(0x40)
    1922
                m3 := mload(0x60)
    1923
                // Selector of `log(uint256,bool,uint256)`.
    1924
                mstore(0x00, 0x20098014)
    1925
                mstore(0x20, p0)
    1926
                mstore(0x40, p1)
    1927
                mstore(0x60, p2)
    1928
            }
    1929
            _sendLogPayload(0x1c, 0x64);
    1930
            /// @solidity memory-safe-assembly
    1931
            assembly {
    1932
                mstore(0x00, m0)
    1933
                mstore(0x20, m1)
    1934
                mstore(0x40, m2)
    1935
                mstore(0x60, m3)
    1936
            }
    1937
        }
    1938
    1939
        function log(uint256 p0, bool p1, bytes32 p2) internal pure {
    1940
            bytes32 m0;
    1941
            bytes32 m1;
    1942
            bytes32 m2;
    1943
            bytes32 m3;
    1944
            bytes32 m4;
    1945
            bytes32 m5;
    1946
            /// @solidity memory-safe-assembly
    1947
            assembly {
    1948
                function writeString(pos, w) {
    1949
                    let length := 0
    1950
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    1951
                    mstore(pos, length)
    1952
                    let shift := sub(256, shl(3, length))
    1953
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    1954
                }
    1955
                m0 := mload(0x00)
    1956
                m1 := mload(0x20)
    1957
                m2 := mload(0x40)
    1958
                m3 := mload(0x60)
    1959
                m4 := mload(0x80)
    1960
                m5 := mload(0xa0)
    1961
                // Selector of `log(uint256,bool,string)`.
    1962
                mstore(0x00, 0x85775021)
    1963
                mstore(0x20, p0)
    1964
                mstore(0x40, p1)
    1965
                mstore(0x60, 0x60)
    1966
                writeString(0x80, p2)
    1967
            }
    1968
            _sendLogPayload(0x1c, 0xa4);
    1969
            /// @solidity memory-safe-assembly
    1970
            assembly {
    1971
                mstore(0x00, m0)
    1972
                mstore(0x20, m1)
    1973
                mstore(0x40, m2)
    1974
                mstore(0x60, m3)
    1975
                mstore(0x80, m4)
    1976
                mstore(0xa0, m5)
    1977
            }
    1978
        }
    1979
    1980
        function log(uint256 p0, uint256 p1, address p2) internal pure {
    1981
            bytes32 m0;
    1982
            bytes32 m1;
    1983
            bytes32 m2;
    1984
            bytes32 m3;
    1985
            /// @solidity memory-safe-assembly
    1986
            assembly {
    1987
                m0 := mload(0x00)
    1988
                m1 := mload(0x20)
    1989
                m2 := mload(0x40)
    1990
                m3 := mload(0x60)
    1991
                // Selector of `log(uint256,uint256,address)`.
    1992
                mstore(0x00, 0x5c96b331)
    1993
                mstore(0x20, p0)
    1994
                mstore(0x40, p1)
    1995
                mstore(0x60, p2)
    1996
            }
    1997
            _sendLogPayload(0x1c, 0x64);
    1998
            /// @solidity memory-safe-assembly
    1999
            assembly {
    2000
                mstore(0x00, m0)
    2001
                mstore(0x20, m1)
    2002
                mstore(0x40, m2)
    2003
                mstore(0x60, m3)
    2004
            }
    2005
        }
    2006
    2007
        function log(uint256 p0, uint256 p1, bool p2) internal pure {
    2008
            bytes32 m0;
    2009
            bytes32 m1;
    2010
            bytes32 m2;
    2011
            bytes32 m3;
    2012
            /// @solidity memory-safe-assembly
    2013
            assembly {
    2014
                m0 := mload(0x00)
    2015
                m1 := mload(0x20)
    2016
                m2 := mload(0x40)
    2017
                m3 := mload(0x60)
    2018
                // Selector of `log(uint256,uint256,bool)`.
    2019
                mstore(0x00, 0x4766da72)
    2020
                mstore(0x20, p0)
    2021
                mstore(0x40, p1)
    2022
                mstore(0x60, p2)
    2023
            }
    2024
            _sendLogPayload(0x1c, 0x64);
    2025
            /// @solidity memory-safe-assembly
    2026
            assembly {
    2027
                mstore(0x00, m0)
    2028
                mstore(0x20, m1)
    2029
                mstore(0x40, m2)
    2030
                mstore(0x60, m3)
    2031
            }
    2032
        }
    2033
    2034
        function log(uint256 p0, uint256 p1, uint256 p2) internal pure {
    2035
            bytes32 m0;
    2036
            bytes32 m1;
    2037
            bytes32 m2;
    2038
            bytes32 m3;
    2039
            /// @solidity memory-safe-assembly
    2040
            assembly {
    2041
                m0 := mload(0x00)
    2042
                m1 := mload(0x20)
    2043
                m2 := mload(0x40)
    2044
                m3 := mload(0x60)
    2045
                // Selector of `log(uint256,uint256,uint256)`.
    2046
                mstore(0x00, 0xd1ed7a3c)
    2047
                mstore(0x20, p0)
    2048
                mstore(0x40, p1)
    2049
                mstore(0x60, p2)
    2050
            }
    2051
            _sendLogPayload(0x1c, 0x64);
    2052
            /// @solidity memory-safe-assembly
    2053
            assembly {
    2054
                mstore(0x00, m0)
    2055
                mstore(0x20, m1)
    2056
                mstore(0x40, m2)
    2057
                mstore(0x60, m3)
    2058
            }
    2059
        }
    2060
    2061
        function log(uint256 p0, uint256 p1, bytes32 p2) internal pure {
    2062
            bytes32 m0;
    2063
            bytes32 m1;
    2064
            bytes32 m2;
    2065
            bytes32 m3;
    2066
            bytes32 m4;
    2067
            bytes32 m5;
    2068
            /// @solidity memory-safe-assembly
    2069
            assembly {
    2070
                function writeString(pos, w) {
    2071
                    let length := 0
    2072
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    2073
                    mstore(pos, length)
    2074
                    let shift := sub(256, shl(3, length))
    2075
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    2076
                }
    2077
                m0 := mload(0x00)
    2078
                m1 := mload(0x20)
    2079
                m2 := mload(0x40)
    2080
                m3 := mload(0x60)
    2081
                m4 := mload(0x80)
    2082
                m5 := mload(0xa0)
    2083
                // Selector of `log(uint256,uint256,string)`.
    2084
                mstore(0x00, 0x71d04af2)
    2085
                mstore(0x20, p0)
    2086
                mstore(0x40, p1)
    2087
                mstore(0x60, 0x60)
    2088
                writeString(0x80, p2)
    2089
            }
    2090
            _sendLogPayload(0x1c, 0xa4);
    2091
            /// @solidity memory-safe-assembly
    2092
            assembly {
    2093
                mstore(0x00, m0)
    2094
                mstore(0x20, m1)
    2095
                mstore(0x40, m2)
    2096
                mstore(0x60, m3)
    2097
                mstore(0x80, m4)
    2098
                mstore(0xa0, m5)
    2099
            }
    2100
        }
    2101
    2102
        function log(uint256 p0, bytes32 p1, address p2) internal pure {
    2103
            bytes32 m0;
    2104
            bytes32 m1;
    2105
            bytes32 m2;
    2106
            bytes32 m3;
    2107
            bytes32 m4;
    2108
            bytes32 m5;
    2109
            /// @solidity memory-safe-assembly
    2110
            assembly {
    2111
                function writeString(pos, w) {
    2112
                    let length := 0
    2113
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    2114
                    mstore(pos, length)
    2115
                    let shift := sub(256, shl(3, length))
    2116
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    2117
                }
    2118
                m0 := mload(0x00)
    2119
                m1 := mload(0x20)
    2120
                m2 := mload(0x40)
    2121
                m3 := mload(0x60)
    2122
                m4 := mload(0x80)
    2123
                m5 := mload(0xa0)
    2124
                // Selector of `log(uint256,string,address)`.
    2125
                mstore(0x00, 0x7afac959)
    2126
                mstore(0x20, p0)
    2127
                mstore(0x40, 0x60)
    2128
                mstore(0x60, p2)
    2129
                writeString(0x80, p1)
    2130
            }
    2131
            _sendLogPayload(0x1c, 0xa4);
    2132
            /// @solidity memory-safe-assembly
    2133
            assembly {
    2134
                mstore(0x00, m0)
    2135
                mstore(0x20, m1)
    2136
                mstore(0x40, m2)
    2137
                mstore(0x60, m3)
    2138
                mstore(0x80, m4)
    2139
                mstore(0xa0, m5)
    2140
            }
    2141
        }
    2142
    2143
        function log(uint256 p0, bytes32 p1, bool p2) internal pure {
    2144
            bytes32 m0;
    2145
            bytes32 m1;
    2146
            bytes32 m2;
    2147
            bytes32 m3;
    2148
            bytes32 m4;
    2149
            bytes32 m5;
    2150
            /// @solidity memory-safe-assembly
    2151
            assembly {
    2152
                function writeString(pos, w) {
    2153
                    let length := 0
    2154
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    2155
                    mstore(pos, length)
    2156
                    let shift := sub(256, shl(3, length))
    2157
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    2158
                }
    2159
                m0 := mload(0x00)
    2160
                m1 := mload(0x20)
    2161
                m2 := mload(0x40)
    2162
                m3 := mload(0x60)
    2163
                m4 := mload(0x80)
    2164
                m5 := mload(0xa0)
    2165
                // Selector of `log(uint256,string,bool)`.
    2166
                mstore(0x00, 0x4ceda75a)
    2167
                mstore(0x20, p0)
    2168
                mstore(0x40, 0x60)
    2169
                mstore(0x60, p2)
    2170
                writeString(0x80, p1)
    2171
            }
    2172
            _sendLogPayload(0x1c, 0xa4);
    2173
            /// @solidity memory-safe-assembly
    2174
            assembly {
    2175
                mstore(0x00, m0)
    2176
                mstore(0x20, m1)
    2177
                mstore(0x40, m2)
    2178
                mstore(0x60, m3)
    2179
                mstore(0x80, m4)
    2180
                mstore(0xa0, m5)
    2181
            }
    2182
        }
    2183
    2184
        function log(uint256 p0, bytes32 p1, uint256 p2) internal pure {
    2185
            bytes32 m0;
    2186
            bytes32 m1;
    2187
            bytes32 m2;
    2188
            bytes32 m3;
    2189
            bytes32 m4;
    2190
            bytes32 m5;
    2191
            /// @solidity memory-safe-assembly
    2192
            assembly {
    2193
                function writeString(pos, w) {
    2194
                    let length := 0
    2195
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    2196
                    mstore(pos, length)
    2197
                    let shift := sub(256, shl(3, length))
    2198
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    2199
                }
    2200
                m0 := mload(0x00)
    2201
                m1 := mload(0x20)
    2202
                m2 := mload(0x40)
    2203
                m3 := mload(0x60)
    2204
                m4 := mload(0x80)
    2205
                m5 := mload(0xa0)
    2206
                // Selector of `log(uint256,string,uint256)`.
    2207
                mstore(0x00, 0x37aa7d4c)
    2208
                mstore(0x20, p0)
    2209
                mstore(0x40, 0x60)
    2210
                mstore(0x60, p2)
    2211
                writeString(0x80, p1)
    2212
            }
    2213
            _sendLogPayload(0x1c, 0xa4);
    2214
            /// @solidity memory-safe-assembly
    2215
            assembly {
    2216
                mstore(0x00, m0)
    2217
                mstore(0x20, m1)
    2218
                mstore(0x40, m2)
    2219
                mstore(0x60, m3)
    2220
                mstore(0x80, m4)
    2221
                mstore(0xa0, m5)
    2222
            }
    2223
        }
    2224
    2225
        function log(uint256 p0, bytes32 p1, bytes32 p2) internal pure {
    2226
            bytes32 m0;
    2227
            bytes32 m1;
    2228
            bytes32 m2;
    2229
            bytes32 m3;
    2230
            bytes32 m4;
    2231
            bytes32 m5;
    2232
            bytes32 m6;
    2233
            bytes32 m7;
    2234
            /// @solidity memory-safe-assembly
    2235
            assembly {
    2236
                function writeString(pos, w) {
    2237
                    let length := 0
    2238
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    2239
                    mstore(pos, length)
    2240
                    let shift := sub(256, shl(3, length))
    2241
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    2242
                }
    2243
                m0 := mload(0x00)
    2244
                m1 := mload(0x20)
    2245
                m2 := mload(0x40)
    2246
                m3 := mload(0x60)
    2247
                m4 := mload(0x80)
    2248
                m5 := mload(0xa0)
    2249
                m6 := mload(0xc0)
    2250
                m7 := mload(0xe0)
    2251
                // Selector of `log(uint256,string,string)`.
    2252
                mstore(0x00, 0xb115611f)
    2253
                mstore(0x20, p0)
    2254
                mstore(0x40, 0x60)
    2255
                mstore(0x60, 0xa0)
    2256
                writeString(0x80, p1)
    2257
                writeString(0xc0, p2)
    2258
            }
    2259
            _sendLogPayload(0x1c, 0xe4);
    2260
            /// @solidity memory-safe-assembly
    2261
            assembly {
    2262
                mstore(0x00, m0)
    2263
                mstore(0x20, m1)
    2264
                mstore(0x40, m2)
    2265
                mstore(0x60, m3)
    2266
                mstore(0x80, m4)
    2267
                mstore(0xa0, m5)
    2268
                mstore(0xc0, m6)
    2269
                mstore(0xe0, m7)
    2270
            }
    2271
        }
    2272
    2273
        function log(bytes32 p0, address p1, address p2) internal pure {
    2274
            bytes32 m0;
    2275
            bytes32 m1;
    2276
            bytes32 m2;
    2277
            bytes32 m3;
    2278
            bytes32 m4;
    2279
            bytes32 m5;
    2280
            /// @solidity memory-safe-assembly
    2281
            assembly {
    2282
                function writeString(pos, w) {
    2283
                    let length := 0
    2284
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    2285
                    mstore(pos, length)
    2286
                    let shift := sub(256, shl(3, length))
    2287
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    2288
                }
    2289
                m0 := mload(0x00)
    2290
                m1 := mload(0x20)
    2291
                m2 := mload(0x40)
    2292
                m3 := mload(0x60)
    2293
                m4 := mload(0x80)
    2294
                m5 := mload(0xa0)
    2295
                // Selector of `log(string,address,address)`.
    2296
                mstore(0x00, 0xfcec75e0)
    2297
                mstore(0x20, 0x60)
    2298
                mstore(0x40, p1)
    2299
                mstore(0x60, p2)
    2300
                writeString(0x80, p0)
    2301
            }
    2302
            _sendLogPayload(0x1c, 0xa4);
    2303
            /// @solidity memory-safe-assembly
    2304
            assembly {
    2305
                mstore(0x00, m0)
    2306
                mstore(0x20, m1)
    2307
                mstore(0x40, m2)
    2308
                mstore(0x60, m3)
    2309
                mstore(0x80, m4)
    2310
                mstore(0xa0, m5)
    2311
            }
    2312
        }
    2313
    2314
        function log(bytes32 p0, address p1, bool p2) internal pure {
    2315
            bytes32 m0;
    2316
            bytes32 m1;
    2317
            bytes32 m2;
    2318
            bytes32 m3;
    2319
            bytes32 m4;
    2320
            bytes32 m5;
    2321
            /// @solidity memory-safe-assembly
    2322
            assembly {
    2323
                function writeString(pos, w) {
    2324
                    let length := 0
    2325
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    2326
                    mstore(pos, length)
    2327
                    let shift := sub(256, shl(3, length))
    2328
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    2329
                }
    2330
                m0 := mload(0x00)
    2331
                m1 := mload(0x20)
    2332
                m2 := mload(0x40)
    2333
                m3 := mload(0x60)
    2334
                m4 := mload(0x80)
    2335
                m5 := mload(0xa0)
    2336
                // Selector of `log(string,address,bool)`.
    2337
                mstore(0x00, 0xc91d5ed4)
    2338
                mstore(0x20, 0x60)
    2339
                mstore(0x40, p1)
    2340
                mstore(0x60, p2)
    2341
                writeString(0x80, p0)
    2342
            }
    2343
            _sendLogPayload(0x1c, 0xa4);
    2344
            /// @solidity memory-safe-assembly
    2345
            assembly {
    2346
                mstore(0x00, m0)
    2347
                mstore(0x20, m1)
    2348
                mstore(0x40, m2)
    2349
                mstore(0x60, m3)
    2350
                mstore(0x80, m4)
    2351
                mstore(0xa0, m5)
    2352
            }
    2353
        }
    2354
    2355
        function log(bytes32 p0, address p1, uint256 p2) internal pure {
    2356
            bytes32 m0;
    2357
            bytes32 m1;
    2358
            bytes32 m2;
    2359
            bytes32 m3;
    2360
            bytes32 m4;
    2361
            bytes32 m5;
    2362
            /// @solidity memory-safe-assembly
    2363
            assembly {
    2364
                function writeString(pos, w) {
    2365
                    let length := 0
    2366
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    2367
                    mstore(pos, length)
    2368
                    let shift := sub(256, shl(3, length))
    2369
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    2370
                }
    2371
                m0 := mload(0x00)
    2372
                m1 := mload(0x20)
    2373
                m2 := mload(0x40)
    2374
                m3 := mload(0x60)
    2375
                m4 := mload(0x80)
    2376
                m5 := mload(0xa0)
    2377
                // Selector of `log(string,address,uint256)`.
    2378
                mstore(0x00, 0x0d26b925)
    2379
                mstore(0x20, 0x60)
    2380
                mstore(0x40, p1)
    2381
                mstore(0x60, p2)
    2382
                writeString(0x80, p0)
    2383
            }
    2384
            _sendLogPayload(0x1c, 0xa4);
    2385
            /// @solidity memory-safe-assembly
    2386
            assembly {
    2387
                mstore(0x00, m0)
    2388
                mstore(0x20, m1)
    2389
                mstore(0x40, m2)
    2390
                mstore(0x60, m3)
    2391
                mstore(0x80, m4)
    2392
                mstore(0xa0, m5)
    2393
            }
    2394
        }
    2395
    2396
        function log(bytes32 p0, address p1, bytes32 p2) internal pure {
    2397
            bytes32 m0;
    2398
            bytes32 m1;
    2399
            bytes32 m2;
    2400
            bytes32 m3;
    2401
            bytes32 m4;
    2402
            bytes32 m5;
    2403
            bytes32 m6;
    2404
            bytes32 m7;
    2405
            /// @solidity memory-safe-assembly
    2406
            assembly {
    2407
                function writeString(pos, w) {
    2408
                    let length := 0
    2409
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    2410
                    mstore(pos, length)
    2411
                    let shift := sub(256, shl(3, length))
    2412
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    2413
                }
    2414
                m0 := mload(0x00)
    2415
                m1 := mload(0x20)
    2416
                m2 := mload(0x40)
    2417
                m3 := mload(0x60)
    2418
                m4 := mload(0x80)
    2419
                m5 := mload(0xa0)
    2420
                m6 := mload(0xc0)
    2421
                m7 := mload(0xe0)
    2422
                // Selector of `log(string,address,string)`.
    2423
                mstore(0x00, 0xe0e9ad4f)
    2424
                mstore(0x20, 0x60)
    2425
                mstore(0x40, p1)
    2426
                mstore(0x60, 0xa0)
    2427
                writeString(0x80, p0)
    2428
                writeString(0xc0, p2)
    2429
            }
    2430
            _sendLogPayload(0x1c, 0xe4);
    2431
            /// @solidity memory-safe-assembly
    2432
            assembly {
    2433
                mstore(0x00, m0)
    2434
                mstore(0x20, m1)
    2435
                mstore(0x40, m2)
    2436
                mstore(0x60, m3)
    2437
                mstore(0x80, m4)
    2438
                mstore(0xa0, m5)
    2439
                mstore(0xc0, m6)
    2440
                mstore(0xe0, m7)
    2441
            }
    2442
        }
    2443
    2444
        function log(bytes32 p0, bool p1, address p2) internal pure {
    2445
            bytes32 m0;
    2446
            bytes32 m1;
    2447
            bytes32 m2;
    2448
            bytes32 m3;
    2449
            bytes32 m4;
    2450
            bytes32 m5;
    2451
            /// @solidity memory-safe-assembly
    2452
            assembly {
    2453
                function writeString(pos, w) {
    2454
                    let length := 0
    2455
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    2456
                    mstore(pos, length)
    2457
                    let shift := sub(256, shl(3, length))
    2458
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    2459
                }
    2460
                m0 := mload(0x00)
    2461
                m1 := mload(0x20)
    2462
                m2 := mload(0x40)
    2463
                m3 := mload(0x60)
    2464
                m4 := mload(0x80)
    2465
                m5 := mload(0xa0)
    2466
                // Selector of `log(string,bool,address)`.
    2467
                mstore(0x00, 0x932bbb38)
    2468
                mstore(0x20, 0x60)
    2469
                mstore(0x40, p1)
    2470
                mstore(0x60, p2)
    2471
                writeString(0x80, p0)
    2472
            }
    2473
            _sendLogPayload(0x1c, 0xa4);
    2474
            /// @solidity memory-safe-assembly
    2475
            assembly {
    2476
                mstore(0x00, m0)
    2477
                mstore(0x20, m1)
    2478
                mstore(0x40, m2)
    2479
                mstore(0x60, m3)
    2480
                mstore(0x80, m4)
    2481
                mstore(0xa0, m5)
    2482
            }
    2483
        }
    2484
    2485
        function log(bytes32 p0, bool p1, bool p2) internal pure {
    2486
            bytes32 m0;
    2487
            bytes32 m1;
    2488
            bytes32 m2;
    2489
            bytes32 m3;
    2490
            bytes32 m4;
    2491
            bytes32 m5;
    2492
            /// @solidity memory-safe-assembly
    2493
            assembly {
    2494
                function writeString(pos, w) {
    2495
                    let length := 0
    2496
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    2497
                    mstore(pos, length)
    2498
                    let shift := sub(256, shl(3, length))
    2499
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    2500
                }
    2501
                m0 := mload(0x00)
    2502
                m1 := mload(0x20)
    2503
                m2 := mload(0x40)
    2504
                m3 := mload(0x60)
    2505
                m4 := mload(0x80)
    2506
                m5 := mload(0xa0)
    2507
                // Selector of `log(string,bool,bool)`.
    2508
                mstore(0x00, 0x850b7ad6)
    2509
                mstore(0x20, 0x60)
    2510
                mstore(0x40, p1)
    2511
                mstore(0x60, p2)
    2512
                writeString(0x80, p0)
    2513
            }
    2514
            _sendLogPayload(0x1c, 0xa4);
    2515
            /// @solidity memory-safe-assembly
    2516
            assembly {
    2517
                mstore(0x00, m0)
    2518
                mstore(0x20, m1)
    2519
                mstore(0x40, m2)
    2520
                mstore(0x60, m3)
    2521
                mstore(0x80, m4)
    2522
                mstore(0xa0, m5)
    2523
            }
    2524
        }
    2525
    2526
        function log(bytes32 p0, bool p1, uint256 p2) internal pure {
    2527
            bytes32 m0;
    2528
            bytes32 m1;
    2529
            bytes32 m2;
    2530
            bytes32 m3;
    2531
            bytes32 m4;
    2532
            bytes32 m5;
    2533
            /// @solidity memory-safe-assembly
    2534
            assembly {
    2535
                function writeString(pos, w) {
    2536
                    let length := 0
    2537
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    2538
                    mstore(pos, length)
    2539
                    let shift := sub(256, shl(3, length))
    2540
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    2541
                }
    2542
                m0 := mload(0x00)
    2543
                m1 := mload(0x20)
    2544
                m2 := mload(0x40)
    2545
                m3 := mload(0x60)
    2546
                m4 := mload(0x80)
    2547
                m5 := mload(0xa0)
    2548
                // Selector of `log(string,bool,uint256)`.
    2549
                mstore(0x00, 0xc95958d6)
    2550
                mstore(0x20, 0x60)
    2551
                mstore(0x40, p1)
    2552
                mstore(0x60, p2)
    2553
                writeString(0x80, p0)
    2554
            }
    2555
            _sendLogPayload(0x1c, 0xa4);
    2556
            /// @solidity memory-safe-assembly
    2557
            assembly {
    2558
                mstore(0x00, m0)
    2559
                mstore(0x20, m1)
    2560
                mstore(0x40, m2)
    2561
                mstore(0x60, m3)
    2562
                mstore(0x80, m4)
    2563
                mstore(0xa0, m5)
    2564
            }
    2565
        }
    2566
    2567
        function log(bytes32 p0, bool p1, bytes32 p2) internal pure {
    2568
            bytes32 m0;
    2569
            bytes32 m1;
    2570
            bytes32 m2;
    2571
            bytes32 m3;
    2572
            bytes32 m4;
    2573
            bytes32 m5;
    2574
            bytes32 m6;
    2575
            bytes32 m7;
    2576
            /// @solidity memory-safe-assembly
    2577
            assembly {
    2578
                function writeString(pos, w) {
    2579
                    let length := 0
    2580
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    2581
                    mstore(pos, length)
    2582
                    let shift := sub(256, shl(3, length))
    2583
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    2584
                }
    2585
                m0 := mload(0x00)
    2586
                m1 := mload(0x20)
    2587
                m2 := mload(0x40)
    2588
                m3 := mload(0x60)
    2589
                m4 := mload(0x80)
    2590
                m5 := mload(0xa0)
    2591
                m6 := mload(0xc0)
    2592
                m7 := mload(0xe0)
    2593
                // Selector of `log(string,bool,string)`.
    2594
                mstore(0x00, 0xe298f47d)
    2595
                mstore(0x20, 0x60)
    2596
                mstore(0x40, p1)
    2597
                mstore(0x60, 0xa0)
    2598
                writeString(0x80, p0)
    2599
                writeString(0xc0, p2)
    2600
            }
    2601
            _sendLogPayload(0x1c, 0xe4);
    2602
            /// @solidity memory-safe-assembly
    2603
            assembly {
    2604
                mstore(0x00, m0)
    2605
                mstore(0x20, m1)
    2606
                mstore(0x40, m2)
    2607
                mstore(0x60, m3)
    2608
                mstore(0x80, m4)
    2609
                mstore(0xa0, m5)
    2610
                mstore(0xc0, m6)
    2611
                mstore(0xe0, m7)
    2612
            }
    2613
        }
    2614
    2615
        function log(bytes32 p0, uint256 p1, address p2) internal pure {
    2616
            bytes32 m0;
    2617
            bytes32 m1;
    2618
            bytes32 m2;
    2619
            bytes32 m3;
    2620
            bytes32 m4;
    2621
            bytes32 m5;
    2622
            /// @solidity memory-safe-assembly
    2623
            assembly {
    2624
                function writeString(pos, w) {
    2625
                    let length := 0
    2626
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    2627
                    mstore(pos, length)
    2628
                    let shift := sub(256, shl(3, length))
    2629
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    2630
                }
    2631
                m0 := mload(0x00)
    2632
                m1 := mload(0x20)
    2633
                m2 := mload(0x40)
    2634
                m3 := mload(0x60)
    2635
                m4 := mload(0x80)
    2636
                m5 := mload(0xa0)
    2637
                // Selector of `log(string,uint256,address)`.
    2638
                mstore(0x00, 0x1c7ec448)
    2639
                mstore(0x20, 0x60)
    2640
                mstore(0x40, p1)
    2641
                mstore(0x60, p2)
    2642
                writeString(0x80, p0)
    2643
            }
    2644
            _sendLogPayload(0x1c, 0xa4);
    2645
            /// @solidity memory-safe-assembly
    2646
            assembly {
    2647
                mstore(0x00, m0)
    2648
                mstore(0x20, m1)
    2649
                mstore(0x40, m2)
    2650
                mstore(0x60, m3)
    2651
                mstore(0x80, m4)
    2652
                mstore(0xa0, m5)
    2653
            }
    2654
        }
    2655
    2656
        function log(bytes32 p0, uint256 p1, bool p2) internal pure {
    2657
            bytes32 m0;
    2658
            bytes32 m1;
    2659
            bytes32 m2;
    2660
            bytes32 m3;
    2661
            bytes32 m4;
    2662
            bytes32 m5;
    2663
            /// @solidity memory-safe-assembly
    2664
            assembly {
    2665
                function writeString(pos, w) {
    2666
                    let length := 0
    2667
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    2668
                    mstore(pos, length)
    2669
                    let shift := sub(256, shl(3, length))
    2670
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    2671
                }
    2672
                m0 := mload(0x00)
    2673
                m1 := mload(0x20)
    2674
                m2 := mload(0x40)
    2675
                m3 := mload(0x60)
    2676
                m4 := mload(0x80)
    2677
                m5 := mload(0xa0)
    2678
                // Selector of `log(string,uint256,bool)`.
    2679
                mstore(0x00, 0xca7733b1)
    2680
                mstore(0x20, 0x60)
    2681
                mstore(0x40, p1)
    2682
                mstore(0x60, p2)
    2683
                writeString(0x80, p0)
    2684
            }
    2685
            _sendLogPayload(0x1c, 0xa4);
    2686
            /// @solidity memory-safe-assembly
    2687
            assembly {
    2688
                mstore(0x00, m0)
    2689
                mstore(0x20, m1)
    2690
                mstore(0x40, m2)
    2691
                mstore(0x60, m3)
    2692
                mstore(0x80, m4)
    2693
                mstore(0xa0, m5)
    2694
            }
    2695
        }
    2696
    2697
        function log(bytes32 p0, uint256 p1, uint256 p2) internal pure {
    2698
            bytes32 m0;
    2699
            bytes32 m1;
    2700
            bytes32 m2;
    2701
            bytes32 m3;
    2702
            bytes32 m4;
    2703
            bytes32 m5;
    2704
            /// @solidity memory-safe-assembly
    2705
            assembly {
    2706
                function writeString(pos, w) {
    2707
                    let length := 0
    2708
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    2709
                    mstore(pos, length)
    2710
                    let shift := sub(256, shl(3, length))
    2711
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    2712
                }
    2713
                m0 := mload(0x00)
    2714
                m1 := mload(0x20)
    2715
                m2 := mload(0x40)
    2716
                m3 := mload(0x60)
    2717
                m4 := mload(0x80)
    2718
                m5 := mload(0xa0)
    2719
                // Selector of `log(string,uint256,uint256)`.
    2720
                mstore(0x00, 0xca47c4eb)
    2721
                mstore(0x20, 0x60)
    2722
                mstore(0x40, p1)
    2723
                mstore(0x60, p2)
    2724
                writeString(0x80, p0)
    2725
            }
    2726
            _sendLogPayload(0x1c, 0xa4);
    2727
            /// @solidity memory-safe-assembly
    2728
            assembly {
    2729
                mstore(0x00, m0)
    2730
                mstore(0x20, m1)
    2731
                mstore(0x40, m2)
    2732
                mstore(0x60, m3)
    2733
                mstore(0x80, m4)
    2734
                mstore(0xa0, m5)
    2735
            }
    2736
        }
    2737
    2738
        function log(bytes32 p0, uint256 p1, bytes32 p2) internal pure {
    2739
            bytes32 m0;
    2740
            bytes32 m1;
    2741
            bytes32 m2;
    2742
            bytes32 m3;
    2743
            bytes32 m4;
    2744
            bytes32 m5;
    2745
            bytes32 m6;
    2746
            bytes32 m7;
    2747
            /// @solidity memory-safe-assembly
    2748
            assembly {
    2749
                function writeString(pos, w) {
    2750
                    let length := 0
    2751
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    2752
                    mstore(pos, length)
    2753
                    let shift := sub(256, shl(3, length))
    2754
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    2755
                }
    2756
                m0 := mload(0x00)
    2757
                m1 := mload(0x20)
    2758
                m2 := mload(0x40)
    2759
                m3 := mload(0x60)
    2760
                m4 := mload(0x80)
    2761
                m5 := mload(0xa0)
    2762
                m6 := mload(0xc0)
    2763
                m7 := mload(0xe0)
    2764
                // Selector of `log(string,uint256,string)`.
    2765
                mstore(0x00, 0x5970e089)
    2766
                mstore(0x20, 0x60)
    2767
                mstore(0x40, p1)
    2768
                mstore(0x60, 0xa0)
    2769
                writeString(0x80, p0)
    2770
                writeString(0xc0, p2)
    2771
            }
    2772
            _sendLogPayload(0x1c, 0xe4);
    2773
            /// @solidity memory-safe-assembly
    2774
            assembly {
    2775
                mstore(0x00, m0)
    2776
                mstore(0x20, m1)
    2777
                mstore(0x40, m2)
    2778
                mstore(0x60, m3)
    2779
                mstore(0x80, m4)
    2780
                mstore(0xa0, m5)
    2781
                mstore(0xc0, m6)
    2782
                mstore(0xe0, m7)
    2783
            }
    2784
        }
    2785
    2786
        function log(bytes32 p0, bytes32 p1, address p2) internal pure {
    2787
            bytes32 m0;
    2788
            bytes32 m1;
    2789
            bytes32 m2;
    2790
            bytes32 m3;
    2791
            bytes32 m4;
    2792
            bytes32 m5;
    2793
            bytes32 m6;
    2794
            bytes32 m7;
    2795
            /// @solidity memory-safe-assembly
    2796
            assembly {
    2797
                function writeString(pos, w) {
    2798
                    let length := 0
    2799
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    2800
                    mstore(pos, length)
    2801
                    let shift := sub(256, shl(3, length))
    2802
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    2803
                }
    2804
                m0 := mload(0x00)
    2805
                m1 := mload(0x20)
    2806
                m2 := mload(0x40)
    2807
                m3 := mload(0x60)
    2808
                m4 := mload(0x80)
    2809
                m5 := mload(0xa0)
    2810
                m6 := mload(0xc0)
    2811
                m7 := mload(0xe0)
    2812
                // Selector of `log(string,string,address)`.
    2813
                mstore(0x00, 0x95ed0195)
    2814
                mstore(0x20, 0x60)
    2815
                mstore(0x40, 0xa0)
    2816
                mstore(0x60, p2)
    2817
                writeString(0x80, p0)
    2818
                writeString(0xc0, p1)
    2819
            }
    2820
            _sendLogPayload(0x1c, 0xe4);
    2821
            /// @solidity memory-safe-assembly
    2822
            assembly {
    2823
                mstore(0x00, m0)
    2824
                mstore(0x20, m1)
    2825
                mstore(0x40, m2)
    2826
                mstore(0x60, m3)
    2827
                mstore(0x80, m4)
    2828
                mstore(0xa0, m5)
    2829
                mstore(0xc0, m6)
    2830
                mstore(0xe0, m7)
    2831
            }
    2832
        }
    2833
    2834
        function log(bytes32 p0, bytes32 p1, bool p2) internal pure {
    2835
            bytes32 m0;
    2836
            bytes32 m1;
    2837
            bytes32 m2;
    2838
            bytes32 m3;
    2839
            bytes32 m4;
    2840
            bytes32 m5;
    2841
            bytes32 m6;
    2842
            bytes32 m7;
    2843
            /// @solidity memory-safe-assembly
    2844
            assembly {
    2845
                function writeString(pos, w) {
    2846
                    let length := 0
    2847
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    2848
                    mstore(pos, length)
    2849
                    let shift := sub(256, shl(3, length))
    2850
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    2851
                }
    2852
                m0 := mload(0x00)
    2853
                m1 := mload(0x20)
    2854
                m2 := mload(0x40)
    2855
                m3 := mload(0x60)
    2856
                m4 := mload(0x80)
    2857
                m5 := mload(0xa0)
    2858
                m6 := mload(0xc0)
    2859
                m7 := mload(0xe0)
    2860
                // Selector of `log(string,string,bool)`.
    2861
                mstore(0x00, 0xb0e0f9b5)
    2862
                mstore(0x20, 0x60)
    2863
                mstore(0x40, 0xa0)
    2864
                mstore(0x60, p2)
    2865
                writeString(0x80, p0)
    2866
                writeString(0xc0, p1)
    2867
            }
    2868
            _sendLogPayload(0x1c, 0xe4);
    2869
            /// @solidity memory-safe-assembly
    2870
            assembly {
    2871
                mstore(0x00, m0)
    2872
                mstore(0x20, m1)
    2873
                mstore(0x40, m2)
    2874
                mstore(0x60, m3)
    2875
                mstore(0x80, m4)
    2876
                mstore(0xa0, m5)
    2877
                mstore(0xc0, m6)
    2878
                mstore(0xe0, m7)
    2879
            }
    2880
        }
    2881
    2882
        function log(bytes32 p0, bytes32 p1, uint256 p2) internal pure {
    2883
            bytes32 m0;
    2884
            bytes32 m1;
    2885
            bytes32 m2;
    2886
            bytes32 m3;
    2887
            bytes32 m4;
    2888
            bytes32 m5;
    2889
            bytes32 m6;
    2890
            bytes32 m7;
    2891
            /// @solidity memory-safe-assembly
    2892
            assembly {
    2893
                function writeString(pos, w) {
    2894
                    let length := 0
    2895
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    2896
                    mstore(pos, length)
    2897
                    let shift := sub(256, shl(3, length))
    2898
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    2899
                }
    2900
                m0 := mload(0x00)
    2901
                m1 := mload(0x20)
    2902
                m2 := mload(0x40)
    2903
                m3 := mload(0x60)
    2904
                m4 := mload(0x80)
    2905
                m5 := mload(0xa0)
    2906
                m6 := mload(0xc0)
    2907
                m7 := mload(0xe0)
    2908
                // Selector of `log(string,string,uint256)`.
    2909
                mstore(0x00, 0x5821efa1)
    2910
                mstore(0x20, 0x60)
    2911
                mstore(0x40, 0xa0)
    2912
                mstore(0x60, p2)
    2913
                writeString(0x80, p0)
    2914
                writeString(0xc0, p1)
    2915
            }
    2916
            _sendLogPayload(0x1c, 0xe4);
    2917
            /// @solidity memory-safe-assembly
    2918
            assembly {
    2919
                mstore(0x00, m0)
    2920
                mstore(0x20, m1)
    2921
                mstore(0x40, m2)
    2922
                mstore(0x60, m3)
    2923
                mstore(0x80, m4)
    2924
                mstore(0xa0, m5)
    2925
                mstore(0xc0, m6)
    2926
                mstore(0xe0, m7)
    2927
            }
    2928
        }
    2929
    2930
        function log(bytes32 p0, bytes32 p1, bytes32 p2) internal pure {
    2931
            bytes32 m0;
    2932
            bytes32 m1;
    2933
            bytes32 m2;
    2934
            bytes32 m3;
    2935
            bytes32 m4;
    2936
            bytes32 m5;
    2937
            bytes32 m6;
    2938
            bytes32 m7;
    2939
            bytes32 m8;
    2940
            bytes32 m9;
    2941
            /// @solidity memory-safe-assembly
    2942
            assembly {
    2943
                function writeString(pos, w) {
    2944
                    let length := 0
    2945
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    2946
                    mstore(pos, length)
    2947
                    let shift := sub(256, shl(3, length))
    2948
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    2949
                }
    2950
                m0 := mload(0x00)
    2951
                m1 := mload(0x20)
    2952
                m2 := mload(0x40)
    2953
                m3 := mload(0x60)
    2954
                m4 := mload(0x80)
    2955
                m5 := mload(0xa0)
    2956
                m6 := mload(0xc0)
    2957
                m7 := mload(0xe0)
    2958
                m8 := mload(0x100)
    2959
                m9 := mload(0x120)
    2960
                // Selector of `log(string,string,string)`.
    2961
                mstore(0x00, 0x2ced7cef)
    2962
                mstore(0x20, 0x60)
    2963
                mstore(0x40, 0xa0)
    2964
                mstore(0x60, 0xe0)
    2965
                writeString(0x80, p0)
    2966
                writeString(0xc0, p1)
    2967
                writeString(0x100, p2)
    2968
            }
    2969
            _sendLogPayload(0x1c, 0x124);
    2970
            /// @solidity memory-safe-assembly
    2971
            assembly {
    2972
                mstore(0x00, m0)
    2973
                mstore(0x20, m1)
    2974
                mstore(0x40, m2)
    2975
                mstore(0x60, m3)
    2976
                mstore(0x80, m4)
    2977
                mstore(0xa0, m5)
    2978
                mstore(0xc0, m6)
    2979
                mstore(0xe0, m7)
    2980
                mstore(0x100, m8)
    2981
                mstore(0x120, m9)
    2982
            }
    2983
        }
    2984
    2985
        function log(address p0, address p1, address p2, address p3) internal pure {
    2986
            bytes32 m0;
    2987
            bytes32 m1;
    2988
            bytes32 m2;
    2989
            bytes32 m3;
    2990
            bytes32 m4;
    2991
            /// @solidity memory-safe-assembly
    2992
            assembly {
    2993
                m0 := mload(0x00)
    2994
                m1 := mload(0x20)
    2995
                m2 := mload(0x40)
    2996
                m3 := mload(0x60)
    2997
                m4 := mload(0x80)
    2998
                // Selector of `log(address,address,address,address)`.
    2999
                mstore(0x00, 0x665bf134)
    3000
                mstore(0x20, p0)
    3001
                mstore(0x40, p1)
    3002
                mstore(0x60, p2)
    3003
                mstore(0x80, p3)
    3004
            }
    3005
            _sendLogPayload(0x1c, 0x84);
    3006
            /// @solidity memory-safe-assembly
    3007
            assembly {
    3008
                mstore(0x00, m0)
    3009
                mstore(0x20, m1)
    3010
                mstore(0x40, m2)
    3011
                mstore(0x60, m3)
    3012
                mstore(0x80, m4)
    3013
            }
    3014
        }
    3015
    3016
        function log(address p0, address p1, address p2, bool p3) internal pure {
    3017
            bytes32 m0;
    3018
            bytes32 m1;
    3019
            bytes32 m2;
    3020
            bytes32 m3;
    3021
            bytes32 m4;
    3022
            /// @solidity memory-safe-assembly
    3023
            assembly {
    3024
                m0 := mload(0x00)
    3025
                m1 := mload(0x20)
    3026
                m2 := mload(0x40)
    3027
                m3 := mload(0x60)
    3028
                m4 := mload(0x80)
    3029
                // Selector of `log(address,address,address,bool)`.
    3030
                mstore(0x00, 0x0e378994)
    3031
                mstore(0x20, p0)
    3032
                mstore(0x40, p1)
    3033
                mstore(0x60, p2)
    3034
                mstore(0x80, p3)
    3035
            }
    3036
            _sendLogPayload(0x1c, 0x84);
    3037
            /// @solidity memory-safe-assembly
    3038
            assembly {
    3039
                mstore(0x00, m0)
    3040
                mstore(0x20, m1)
    3041
                mstore(0x40, m2)
    3042
                mstore(0x60, m3)
    3043
                mstore(0x80, m4)
    3044
            }
    3045
        }
    3046
    3047
        function log(address p0, address p1, address p2, uint256 p3) internal pure {
    3048
            bytes32 m0;
    3049
            bytes32 m1;
    3050
            bytes32 m2;
    3051
            bytes32 m3;
    3052
            bytes32 m4;
    3053
            /// @solidity memory-safe-assembly
    3054
            assembly {
    3055
                m0 := mload(0x00)
    3056
                m1 := mload(0x20)
    3057
                m2 := mload(0x40)
    3058
                m3 := mload(0x60)
    3059
                m4 := mload(0x80)
    3060
                // Selector of `log(address,address,address,uint256)`.
    3061
                mstore(0x00, 0x94250d77)
    3062
                mstore(0x20, p0)
    3063
                mstore(0x40, p1)
    3064
                mstore(0x60, p2)
    3065
                mstore(0x80, p3)
    3066
            }
    3067
            _sendLogPayload(0x1c, 0x84);
    3068
            /// @solidity memory-safe-assembly
    3069
            assembly {
    3070
                mstore(0x00, m0)
    3071
                mstore(0x20, m1)
    3072
                mstore(0x40, m2)
    3073
                mstore(0x60, m3)
    3074
                mstore(0x80, m4)
    3075
            }
    3076
        }
    3077
    3078
        function log(address p0, address p1, address p2, bytes32 p3) internal pure {
    3079
            bytes32 m0;
    3080
            bytes32 m1;
    3081
            bytes32 m2;
    3082
            bytes32 m3;
    3083
            bytes32 m4;
    3084
            bytes32 m5;
    3085
            bytes32 m6;
    3086
            /// @solidity memory-safe-assembly
    3087
            assembly {
    3088
                function writeString(pos, w) {
    3089
                    let length := 0
    3090
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    3091
                    mstore(pos, length)
    3092
                    let shift := sub(256, shl(3, length))
    3093
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    3094
                }
    3095
                m0 := mload(0x00)
    3096
                m1 := mload(0x20)
    3097
                m2 := mload(0x40)
    3098
                m3 := mload(0x60)
    3099
                m4 := mload(0x80)
    3100
                m5 := mload(0xa0)
    3101
                m6 := mload(0xc0)
    3102
                // Selector of `log(address,address,address,string)`.
    3103
                mstore(0x00, 0xf808da20)
    3104
                mstore(0x20, p0)
    3105
                mstore(0x40, p1)
    3106
                mstore(0x60, p2)
    3107
                mstore(0x80, 0x80)
    3108
                writeString(0xa0, p3)
    3109
            }
    3110
            _sendLogPayload(0x1c, 0xc4);
    3111
            /// @solidity memory-safe-assembly
    3112
            assembly {
    3113
                mstore(0x00, m0)
    3114
                mstore(0x20, m1)
    3115
                mstore(0x40, m2)
    3116
                mstore(0x60, m3)
    3117
                mstore(0x80, m4)
    3118
                mstore(0xa0, m5)
    3119
                mstore(0xc0, m6)
    3120
            }
    3121
        }
    3122
    3123
        function log(address p0, address p1, bool p2, address p3) internal pure {
    3124
            bytes32 m0;
    3125
            bytes32 m1;
    3126
            bytes32 m2;
    3127
            bytes32 m3;
    3128
            bytes32 m4;
    3129
            /// @solidity memory-safe-assembly
    3130
            assembly {
    3131
                m0 := mload(0x00)
    3132
                m1 := mload(0x20)
    3133
                m2 := mload(0x40)
    3134
                m3 := mload(0x60)
    3135
                m4 := mload(0x80)
    3136
                // Selector of `log(address,address,bool,address)`.
    3137
                mstore(0x00, 0x9f1bc36e)
    3138
                mstore(0x20, p0)
    3139
                mstore(0x40, p1)
    3140
                mstore(0x60, p2)
    3141
                mstore(0x80, p3)
    3142
            }
    3143
            _sendLogPayload(0x1c, 0x84);
    3144
            /// @solidity memory-safe-assembly
    3145
            assembly {
    3146
                mstore(0x00, m0)
    3147
                mstore(0x20, m1)
    3148
                mstore(0x40, m2)
    3149
                mstore(0x60, m3)
    3150
                mstore(0x80, m4)
    3151
            }
    3152
        }
    3153
    3154
        function log(address p0, address p1, bool p2, bool p3) internal pure {
    3155
            bytes32 m0;
    3156
            bytes32 m1;
    3157
            bytes32 m2;
    3158
            bytes32 m3;
    3159
            bytes32 m4;
    3160
            /// @solidity memory-safe-assembly
    3161
            assembly {
    3162
                m0 := mload(0x00)
    3163
                m1 := mload(0x20)
    3164
                m2 := mload(0x40)
    3165
                m3 := mload(0x60)
    3166
                m4 := mload(0x80)
    3167
                // Selector of `log(address,address,bool,bool)`.
    3168
                mstore(0x00, 0x2cd4134a)
    3169
                mstore(0x20, p0)
    3170
                mstore(0x40, p1)
    3171
                mstore(0x60, p2)
    3172
                mstore(0x80, p3)
    3173
            }
    3174
            _sendLogPayload(0x1c, 0x84);
    3175
            /// @solidity memory-safe-assembly
    3176
            assembly {
    3177
                mstore(0x00, m0)
    3178
                mstore(0x20, m1)
    3179
                mstore(0x40, m2)
    3180
                mstore(0x60, m3)
    3181
                mstore(0x80, m4)
    3182
            }
    3183
        }
    3184
    3185
        function log(address p0, address p1, bool p2, uint256 p3) internal pure {
    3186
            bytes32 m0;
    3187
            bytes32 m1;
    3188
            bytes32 m2;
    3189
            bytes32 m3;
    3190
            bytes32 m4;
    3191
            /// @solidity memory-safe-assembly
    3192
            assembly {
    3193
                m0 := mload(0x00)
    3194
                m1 := mload(0x20)
    3195
                m2 := mload(0x40)
    3196
                m3 := mload(0x60)
    3197
                m4 := mload(0x80)
    3198
                // Selector of `log(address,address,bool,uint256)`.
    3199
                mstore(0x00, 0x3971e78c)
    3200
                mstore(0x20, p0)
    3201
                mstore(0x40, p1)
    3202
                mstore(0x60, p2)
    3203
                mstore(0x80, p3)
    3204
            }
    3205
            _sendLogPayload(0x1c, 0x84);
    3206
            /// @solidity memory-safe-assembly
    3207
            assembly {
    3208
                mstore(0x00, m0)
    3209
                mstore(0x20, m1)
    3210
                mstore(0x40, m2)
    3211
                mstore(0x60, m3)
    3212
                mstore(0x80, m4)
    3213
            }
    3214
        }
    3215
    3216
        function log(address p0, address p1, bool p2, bytes32 p3) internal pure {
    3217
            bytes32 m0;
    3218
            bytes32 m1;
    3219
            bytes32 m2;
    3220
            bytes32 m3;
    3221
            bytes32 m4;
    3222
            bytes32 m5;
    3223
            bytes32 m6;
    3224
            /// @solidity memory-safe-assembly
    3225
            assembly {
    3226
                function writeString(pos, w) {
    3227
                    let length := 0
    3228
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    3229
                    mstore(pos, length)
    3230
                    let shift := sub(256, shl(3, length))
    3231
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    3232
                }
    3233
                m0 := mload(0x00)
    3234
                m1 := mload(0x20)
    3235
                m2 := mload(0x40)
    3236
                m3 := mload(0x60)
    3237
                m4 := mload(0x80)
    3238
                m5 := mload(0xa0)
    3239
                m6 := mload(0xc0)
    3240
                // Selector of `log(address,address,bool,string)`.
    3241
                mstore(0x00, 0xaa6540c8)
    3242
                mstore(0x20, p0)
    3243
                mstore(0x40, p1)
    3244
                mstore(0x60, p2)
    3245
                mstore(0x80, 0x80)
    3246
                writeString(0xa0, p3)
    3247
            }
    3248
            _sendLogPayload(0x1c, 0xc4);
    3249
            /// @solidity memory-safe-assembly
    3250
            assembly {
    3251
                mstore(0x00, m0)
    3252
                mstore(0x20, m1)
    3253
                mstore(0x40, m2)
    3254
                mstore(0x60, m3)
    3255
                mstore(0x80, m4)
    3256
                mstore(0xa0, m5)
    3257
                mstore(0xc0, m6)
    3258
            }
    3259
        }
    3260
    3261
        function log(address p0, address p1, uint256 p2, address p3) internal pure {
    3262
            bytes32 m0;
    3263
            bytes32 m1;
    3264
            bytes32 m2;
    3265
            bytes32 m3;
    3266
            bytes32 m4;
    3267
            /// @solidity memory-safe-assembly
    3268
            assembly {
    3269
                m0 := mload(0x00)
    3270
                m1 := mload(0x20)
    3271
                m2 := mload(0x40)
    3272
                m3 := mload(0x60)
    3273
                m4 := mload(0x80)
    3274
                // Selector of `log(address,address,uint256,address)`.
    3275
                mstore(0x00, 0x8da6def5)
    3276
                mstore(0x20, p0)
    3277
                mstore(0x40, p1)
    3278
                mstore(0x60, p2)
    3279
                mstore(0x80, p3)
    3280
            }
    3281
            _sendLogPayload(0x1c, 0x84);
    3282
            /// @solidity memory-safe-assembly
    3283
            assembly {
    3284
                mstore(0x00, m0)
    3285
                mstore(0x20, m1)
    3286
                mstore(0x40, m2)
    3287
                mstore(0x60, m3)
    3288
                mstore(0x80, m4)
    3289
            }
    3290
        }
    3291
    3292
        function log(address p0, address p1, uint256 p2, bool p3) internal pure {
    3293
            bytes32 m0;
    3294
            bytes32 m1;
    3295
            bytes32 m2;
    3296
            bytes32 m3;
    3297
            bytes32 m4;
    3298
            /// @solidity memory-safe-assembly
    3299
            assembly {
    3300
                m0 := mload(0x00)
    3301
                m1 := mload(0x20)
    3302
                m2 := mload(0x40)
    3303
                m3 := mload(0x60)
    3304
                m4 := mload(0x80)
    3305
                // Selector of `log(address,address,uint256,bool)`.
    3306
                mstore(0x00, 0x9b4254e2)
    3307
                mstore(0x20, p0)
    3308
                mstore(0x40, p1)
    3309
                mstore(0x60, p2)
    3310
                mstore(0x80, p3)
    3311
            }
    3312
            _sendLogPayload(0x1c, 0x84);
    3313
            /// @solidity memory-safe-assembly
    3314
            assembly {
    3315
                mstore(0x00, m0)
    3316
                mstore(0x20, m1)
    3317
                mstore(0x40, m2)
    3318
                mstore(0x60, m3)
    3319
                mstore(0x80, m4)
    3320
            }
    3321
        }
    3322
    3323
        function log(address p0, address p1, uint256 p2, uint256 p3) internal pure {
    3324
            bytes32 m0;
    3325
            bytes32 m1;
    3326
            bytes32 m2;
    3327
            bytes32 m3;
    3328
            bytes32 m4;
    3329
            /// @solidity memory-safe-assembly
    3330
            assembly {
    3331
                m0 := mload(0x00)
    3332
                m1 := mload(0x20)
    3333
                m2 := mload(0x40)
    3334
                m3 := mload(0x60)
    3335
                m4 := mload(0x80)
    3336
                // Selector of `log(address,address,uint256,uint256)`.
    3337
                mstore(0x00, 0xbe553481)
    3338
                mstore(0x20, p0)
    3339
                mstore(0x40, p1)
    3340
                mstore(0x60, p2)
    3341
                mstore(0x80, p3)
    3342
            }
    3343
            _sendLogPayload(0x1c, 0x84);
    3344
            /// @solidity memory-safe-assembly
    3345
            assembly {
    3346
                mstore(0x00, m0)
    3347
                mstore(0x20, m1)
    3348
                mstore(0x40, m2)
    3349
                mstore(0x60, m3)
    3350
                mstore(0x80, m4)
    3351
            }
    3352
        }
    3353
    3354
        function log(address p0, address p1, uint256 p2, bytes32 p3) internal pure {
    3355
            bytes32 m0;
    3356
            bytes32 m1;
    3357
            bytes32 m2;
    3358
            bytes32 m3;
    3359
            bytes32 m4;
    3360
            bytes32 m5;
    3361
            bytes32 m6;
    3362
            /// @solidity memory-safe-assembly
    3363
            assembly {
    3364
                function writeString(pos, w) {
    3365
                    let length := 0
    3366
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    3367
                    mstore(pos, length)
    3368
                    let shift := sub(256, shl(3, length))
    3369
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    3370
                }
    3371
                m0 := mload(0x00)
    3372
                m1 := mload(0x20)
    3373
                m2 := mload(0x40)
    3374
                m3 := mload(0x60)
    3375
                m4 := mload(0x80)
    3376
                m5 := mload(0xa0)
    3377
                m6 := mload(0xc0)
    3378
                // Selector of `log(address,address,uint256,string)`.
    3379
                mstore(0x00, 0xfdb4f990)
    3380
                mstore(0x20, p0)
    3381
                mstore(0x40, p1)
    3382
                mstore(0x60, p2)
    3383
                mstore(0x80, 0x80)
    3384
                writeString(0xa0, p3)
    3385
            }
    3386
            _sendLogPayload(0x1c, 0xc4);
    3387
            /// @solidity memory-safe-assembly
    3388
            assembly {
    3389
                mstore(0x00, m0)
    3390
                mstore(0x20, m1)
    3391
                mstore(0x40, m2)
    3392
                mstore(0x60, m3)
    3393
                mstore(0x80, m4)
    3394
                mstore(0xa0, m5)
    3395
                mstore(0xc0, m6)
    3396
            }
    3397
        }
    3398
    3399
        function log(address p0, address p1, bytes32 p2, address p3) internal pure {
    3400
            bytes32 m0;
    3401
            bytes32 m1;
    3402
            bytes32 m2;
    3403
            bytes32 m3;
    3404
            bytes32 m4;
    3405
            bytes32 m5;
    3406
            bytes32 m6;
    3407
            /// @solidity memory-safe-assembly
    3408
            assembly {
    3409
                function writeString(pos, w) {
    3410
                    let length := 0
    3411
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    3412
                    mstore(pos, length)
    3413
                    let shift := sub(256, shl(3, length))
    3414
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    3415
                }
    3416
                m0 := mload(0x00)
    3417
                m1 := mload(0x20)
    3418
                m2 := mload(0x40)
    3419
                m3 := mload(0x60)
    3420
                m4 := mload(0x80)
    3421
                m5 := mload(0xa0)
    3422
                m6 := mload(0xc0)
    3423
                // Selector of `log(address,address,string,address)`.
    3424
                mstore(0x00, 0x8f736d16)
    3425
                mstore(0x20, p0)
    3426
                mstore(0x40, p1)
    3427
                mstore(0x60, 0x80)
    3428
                mstore(0x80, p3)
    3429
                writeString(0xa0, p2)
    3430
            }
    3431
            _sendLogPayload(0x1c, 0xc4);
    3432
            /// @solidity memory-safe-assembly
    3433
            assembly {
    3434
                mstore(0x00, m0)
    3435
                mstore(0x20, m1)
    3436
                mstore(0x40, m2)
    3437
                mstore(0x60, m3)
    3438
                mstore(0x80, m4)
    3439
                mstore(0xa0, m5)
    3440
                mstore(0xc0, m6)
    3441
            }
    3442
        }
    3443
    3444
        function log(address p0, address p1, bytes32 p2, bool p3) internal pure {
    3445
            bytes32 m0;
    3446
            bytes32 m1;
    3447
            bytes32 m2;
    3448
            bytes32 m3;
    3449
            bytes32 m4;
    3450
            bytes32 m5;
    3451
            bytes32 m6;
    3452
            /// @solidity memory-safe-assembly
    3453
            assembly {
    3454
                function writeString(pos, w) {
    3455
                    let length := 0
    3456
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    3457
                    mstore(pos, length)
    3458
                    let shift := sub(256, shl(3, length))
    3459
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    3460
                }
    3461
                m0 := mload(0x00)
    3462
                m1 := mload(0x20)
    3463
                m2 := mload(0x40)
    3464
                m3 := mload(0x60)
    3465
                m4 := mload(0x80)
    3466
                m5 := mload(0xa0)
    3467
                m6 := mload(0xc0)
    3468
                // Selector of `log(address,address,string,bool)`.
    3469
                mstore(0x00, 0x6f1a594e)
    3470
                mstore(0x20, p0)
    3471
                mstore(0x40, p1)
    3472
                mstore(0x60, 0x80)
    3473
                mstore(0x80, p3)
    3474
                writeString(0xa0, p2)
    3475
            }
    3476
            _sendLogPayload(0x1c, 0xc4);
    3477
            /// @solidity memory-safe-assembly
    3478
            assembly {
    3479
                mstore(0x00, m0)
    3480
                mstore(0x20, m1)
    3481
                mstore(0x40, m2)
    3482
                mstore(0x60, m3)
    3483
                mstore(0x80, m4)
    3484
                mstore(0xa0, m5)
    3485
                mstore(0xc0, m6)
    3486
            }
    3487
        }
    3488
    3489
        function log(address p0, address p1, bytes32 p2, uint256 p3) internal pure {
    3490
            bytes32 m0;
    3491
            bytes32 m1;
    3492
            bytes32 m2;
    3493
            bytes32 m3;
    3494
            bytes32 m4;
    3495
            bytes32 m5;
    3496
            bytes32 m6;
    3497
            /// @solidity memory-safe-assembly
    3498
            assembly {
    3499
                function writeString(pos, w) {
    3500
                    let length := 0
    3501
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    3502
                    mstore(pos, length)
    3503
                    let shift := sub(256, shl(3, length))
    3504
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    3505
                }
    3506
                m0 := mload(0x00)
    3507
                m1 := mload(0x20)
    3508
                m2 := mload(0x40)
    3509
                m3 := mload(0x60)
    3510
                m4 := mload(0x80)
    3511
                m5 := mload(0xa0)
    3512
                m6 := mload(0xc0)
    3513
                // Selector of `log(address,address,string,uint256)`.
    3514
                mstore(0x00, 0xef1cefe7)
    3515
                mstore(0x20, p0)
    3516
                mstore(0x40, p1)
    3517
                mstore(0x60, 0x80)
    3518
                mstore(0x80, p3)
    3519
                writeString(0xa0, p2)
    3520
            }
    3521
            _sendLogPayload(0x1c, 0xc4);
    3522
            /// @solidity memory-safe-assembly
    3523
            assembly {
    3524
                mstore(0x00, m0)
    3525
                mstore(0x20, m1)
    3526
                mstore(0x40, m2)
    3527
                mstore(0x60, m3)
    3528
                mstore(0x80, m4)
    3529
                mstore(0xa0, m5)
    3530
                mstore(0xc0, m6)
    3531
            }
    3532
        }
    3533
    3534
        function log(address p0, address p1, bytes32 p2, bytes32 p3) internal pure {
    3535
            bytes32 m0;
    3536
            bytes32 m1;
    3537
            bytes32 m2;
    3538
            bytes32 m3;
    3539
            bytes32 m4;
    3540
            bytes32 m5;
    3541
            bytes32 m6;
    3542
            bytes32 m7;
    3543
            bytes32 m8;
    3544
            /// @solidity memory-safe-assembly
    3545
            assembly {
    3546
                function writeString(pos, w) {
    3547
                    let length := 0
    3548
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    3549
                    mstore(pos, length)
    3550
                    let shift := sub(256, shl(3, length))
    3551
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    3552
                }
    3553
                m0 := mload(0x00)
    3554
                m1 := mload(0x20)
    3555
                m2 := mload(0x40)
    3556
                m3 := mload(0x60)
    3557
                m4 := mload(0x80)
    3558
                m5 := mload(0xa0)
    3559
                m6 := mload(0xc0)
    3560
                m7 := mload(0xe0)
    3561
                m8 := mload(0x100)
    3562
                // Selector of `log(address,address,string,string)`.
    3563
                mstore(0x00, 0x21bdaf25)
    3564
                mstore(0x20, p0)
    3565
                mstore(0x40, p1)
    3566
                mstore(0x60, 0x80)
    3567
                mstore(0x80, 0xc0)
    3568
                writeString(0xa0, p2)
    3569
                writeString(0xe0, p3)
    3570
            }
    3571
            _sendLogPayload(0x1c, 0x104);
    3572
            /// @solidity memory-safe-assembly
    3573
            assembly {
    3574
                mstore(0x00, m0)
    3575
                mstore(0x20, m1)
    3576
                mstore(0x40, m2)
    3577
                mstore(0x60, m3)
    3578
                mstore(0x80, m4)
    3579
                mstore(0xa0, m5)
    3580
                mstore(0xc0, m6)
    3581
                mstore(0xe0, m7)
    3582
                mstore(0x100, m8)
    3583
            }
    3584
        }
    3585
    3586
        function log(address p0, bool p1, address p2, address p3) internal pure {
    3587
            bytes32 m0;
    3588
            bytes32 m1;
    3589
            bytes32 m2;
    3590
            bytes32 m3;
    3591
            bytes32 m4;
    3592
            /// @solidity memory-safe-assembly
    3593
            assembly {
    3594
                m0 := mload(0x00)
    3595
                m1 := mload(0x20)
    3596
                m2 := mload(0x40)
    3597
                m3 := mload(0x60)
    3598
                m4 := mload(0x80)
    3599
                // Selector of `log(address,bool,address,address)`.
    3600
                mstore(0x00, 0x660375dd)
    3601
                mstore(0x20, p0)
    3602
                mstore(0x40, p1)
    3603
                mstore(0x60, p2)
    3604
                mstore(0x80, p3)
    3605
            }
    3606
            _sendLogPayload(0x1c, 0x84);
    3607
            /// @solidity memory-safe-assembly
    3608
            assembly {
    3609
                mstore(0x00, m0)
    3610
                mstore(0x20, m1)
    3611
                mstore(0x40, m2)
    3612
                mstore(0x60, m3)
    3613
                mstore(0x80, m4)
    3614
            }
    3615
        }
    3616
    3617
        function log(address p0, bool p1, address p2, bool p3) internal pure {
    3618
            bytes32 m0;
    3619
            bytes32 m1;
    3620
            bytes32 m2;
    3621
            bytes32 m3;
    3622
            bytes32 m4;
    3623
            /// @solidity memory-safe-assembly
    3624
            assembly {
    3625
                m0 := mload(0x00)
    3626
                m1 := mload(0x20)
    3627
                m2 := mload(0x40)
    3628
                m3 := mload(0x60)
    3629
                m4 := mload(0x80)
    3630
                // Selector of `log(address,bool,address,bool)`.
    3631
                mstore(0x00, 0xa6f50b0f)
    3632
                mstore(0x20, p0)
    3633
                mstore(0x40, p1)
    3634
                mstore(0x60, p2)
    3635
                mstore(0x80, p3)
    3636
            }
    3637
            _sendLogPayload(0x1c, 0x84);
    3638
            /// @solidity memory-safe-assembly
    3639
            assembly {
    3640
                mstore(0x00, m0)
    3641
                mstore(0x20, m1)
    3642
                mstore(0x40, m2)
    3643
                mstore(0x60, m3)
    3644
                mstore(0x80, m4)
    3645
            }
    3646
        }
    3647
    3648
        function log(address p0, bool p1, address p2, uint256 p3) internal pure {
    3649
            bytes32 m0;
    3650
            bytes32 m1;
    3651
            bytes32 m2;
    3652
            bytes32 m3;
    3653
            bytes32 m4;
    3654
            /// @solidity memory-safe-assembly
    3655
            assembly {
    3656
                m0 := mload(0x00)
    3657
                m1 := mload(0x20)
    3658
                m2 := mload(0x40)
    3659
                m3 := mload(0x60)
    3660
                m4 := mload(0x80)
    3661
                // Selector of `log(address,bool,address,uint256)`.
    3662
                mstore(0x00, 0xa75c59de)
    3663
                mstore(0x20, p0)
    3664
                mstore(0x40, p1)
    3665
                mstore(0x60, p2)
    3666
                mstore(0x80, p3)
    3667
            }
    3668
            _sendLogPayload(0x1c, 0x84);
    3669
            /// @solidity memory-safe-assembly
    3670
            assembly {
    3671
                mstore(0x00, m0)
    3672
                mstore(0x20, m1)
    3673
                mstore(0x40, m2)
    3674
                mstore(0x60, m3)
    3675
                mstore(0x80, m4)
    3676
            }
    3677
        }
    3678
    3679
        function log(address p0, bool p1, address p2, bytes32 p3) internal pure {
    3680
            bytes32 m0;
    3681
            bytes32 m1;
    3682
            bytes32 m2;
    3683
            bytes32 m3;
    3684
            bytes32 m4;
    3685
            bytes32 m5;
    3686
            bytes32 m6;
    3687
            /// @solidity memory-safe-assembly
    3688
            assembly {
    3689
                function writeString(pos, w) {
    3690
                    let length := 0
    3691
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    3692
                    mstore(pos, length)
    3693
                    let shift := sub(256, shl(3, length))
    3694
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    3695
                }
    3696
                m0 := mload(0x00)
    3697
                m1 := mload(0x20)
    3698
                m2 := mload(0x40)
    3699
                m3 := mload(0x60)
    3700
                m4 := mload(0x80)
    3701
                m5 := mload(0xa0)
    3702
                m6 := mload(0xc0)
    3703
                // Selector of `log(address,bool,address,string)`.
    3704
                mstore(0x00, 0x2dd778e6)
    3705
                mstore(0x20, p0)
    3706
                mstore(0x40, p1)
    3707
                mstore(0x60, p2)
    3708
                mstore(0x80, 0x80)
    3709
                writeString(0xa0, p3)
    3710
            }
    3711
            _sendLogPayload(0x1c, 0xc4);
    3712
            /// @solidity memory-safe-assembly
    3713
            assembly {
    3714
                mstore(0x00, m0)
    3715
                mstore(0x20, m1)
    3716
                mstore(0x40, m2)
    3717
                mstore(0x60, m3)
    3718
                mstore(0x80, m4)
    3719
                mstore(0xa0, m5)
    3720
                mstore(0xc0, m6)
    3721
            }
    3722
        }
    3723
    3724
        function log(address p0, bool p1, bool p2, address p3) internal pure {
    3725
            bytes32 m0;
    3726
            bytes32 m1;
    3727
            bytes32 m2;
    3728
            bytes32 m3;
    3729
            bytes32 m4;
    3730
            /// @solidity memory-safe-assembly
    3731
            assembly {
    3732
                m0 := mload(0x00)
    3733
                m1 := mload(0x20)
    3734
                m2 := mload(0x40)
    3735
                m3 := mload(0x60)
    3736
                m4 := mload(0x80)
    3737
                // Selector of `log(address,bool,bool,address)`.
    3738
                mstore(0x00, 0xcf394485)
    3739
                mstore(0x20, p0)
    3740
                mstore(0x40, p1)
    3741
                mstore(0x60, p2)
    3742
                mstore(0x80, p3)
    3743
            }
    3744
            _sendLogPayload(0x1c, 0x84);
    3745
            /// @solidity memory-safe-assembly
    3746
            assembly {
    3747
                mstore(0x00, m0)
    3748
                mstore(0x20, m1)
    3749
                mstore(0x40, m2)
    3750
                mstore(0x60, m3)
    3751
                mstore(0x80, m4)
    3752
            }
    3753
        }
    3754
    3755
        function log(address p0, bool p1, bool p2, bool p3) internal pure {
    3756
            bytes32 m0;
    3757
            bytes32 m1;
    3758
            bytes32 m2;
    3759
            bytes32 m3;
    3760
            bytes32 m4;
    3761
            /// @solidity memory-safe-assembly
    3762
            assembly {
    3763
                m0 := mload(0x00)
    3764
                m1 := mload(0x20)
    3765
                m2 := mload(0x40)
    3766
                m3 := mload(0x60)
    3767
                m4 := mload(0x80)
    3768
                // Selector of `log(address,bool,bool,bool)`.
    3769
                mstore(0x00, 0xcac43479)
    3770
                mstore(0x20, p0)
    3771
                mstore(0x40, p1)
    3772
                mstore(0x60, p2)
    3773
                mstore(0x80, p3)
    3774
            }
    3775
            _sendLogPayload(0x1c, 0x84);
    3776
            /// @solidity memory-safe-assembly
    3777
            assembly {
    3778
                mstore(0x00, m0)
    3779
                mstore(0x20, m1)
    3780
                mstore(0x40, m2)
    3781
                mstore(0x60, m3)
    3782
                mstore(0x80, m4)
    3783
            }
    3784
        }
    3785
    3786
        function log(address p0, bool p1, bool p2, uint256 p3) internal pure {
    3787
            bytes32 m0;
    3788
            bytes32 m1;
    3789
            bytes32 m2;
    3790
            bytes32 m3;
    3791
            bytes32 m4;
    3792
            /// @solidity memory-safe-assembly
    3793
            assembly {
    3794
                m0 := mload(0x00)
    3795
                m1 := mload(0x20)
    3796
                m2 := mload(0x40)
    3797
                m3 := mload(0x60)
    3798
                m4 := mload(0x80)
    3799
                // Selector of `log(address,bool,bool,uint256)`.
    3800
                mstore(0x00, 0x8c4e5de6)
    3801
                mstore(0x20, p0)
    3802
                mstore(0x40, p1)
    3803
                mstore(0x60, p2)
    3804
                mstore(0x80, p3)
    3805
            }
    3806
            _sendLogPayload(0x1c, 0x84);
    3807
            /// @solidity memory-safe-assembly
    3808
            assembly {
    3809
                mstore(0x00, m0)
    3810
                mstore(0x20, m1)
    3811
                mstore(0x40, m2)
    3812
                mstore(0x60, m3)
    3813
                mstore(0x80, m4)
    3814
            }
    3815
        }
    3816
    3817
        function log(address p0, bool p1, bool p2, bytes32 p3) internal pure {
    3818
            bytes32 m0;
    3819
            bytes32 m1;
    3820
            bytes32 m2;
    3821
            bytes32 m3;
    3822
            bytes32 m4;
    3823
            bytes32 m5;
    3824
            bytes32 m6;
    3825
            /// @solidity memory-safe-assembly
    3826
            assembly {
    3827
                function writeString(pos, w) {
    3828
                    let length := 0
    3829
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    3830
                    mstore(pos, length)
    3831
                    let shift := sub(256, shl(3, length))
    3832
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    3833
                }
    3834
                m0 := mload(0x00)
    3835
                m1 := mload(0x20)
    3836
                m2 := mload(0x40)
    3837
                m3 := mload(0x60)
    3838
                m4 := mload(0x80)
    3839
                m5 := mload(0xa0)
    3840
                m6 := mload(0xc0)
    3841
                // Selector of `log(address,bool,bool,string)`.
    3842
                mstore(0x00, 0xdfc4a2e8)
    3843
                mstore(0x20, p0)
    3844
                mstore(0x40, p1)
    3845
                mstore(0x60, p2)
    3846
                mstore(0x80, 0x80)
    3847
                writeString(0xa0, p3)
    3848
            }
    3849
            _sendLogPayload(0x1c, 0xc4);
    3850
            /// @solidity memory-safe-assembly
    3851
            assembly {
    3852
                mstore(0x00, m0)
    3853
                mstore(0x20, m1)
    3854
                mstore(0x40, m2)
    3855
                mstore(0x60, m3)
    3856
                mstore(0x80, m4)
    3857
                mstore(0xa0, m5)
    3858
                mstore(0xc0, m6)
    3859
            }
    3860
        }
    3861
    3862
        function log(address p0, bool p1, uint256 p2, address p3) internal pure {
    3863
            bytes32 m0;
    3864
            bytes32 m1;
    3865
            bytes32 m2;
    3866
            bytes32 m3;
    3867
            bytes32 m4;
    3868
            /// @solidity memory-safe-assembly
    3869
            assembly {
    3870
                m0 := mload(0x00)
    3871
                m1 := mload(0x20)
    3872
                m2 := mload(0x40)
    3873
                m3 := mload(0x60)
    3874
                m4 := mload(0x80)
    3875
                // Selector of `log(address,bool,uint256,address)`.
    3876
                mstore(0x00, 0xccf790a1)
    3877
                mstore(0x20, p0)
    3878
                mstore(0x40, p1)
    3879
                mstore(0x60, p2)
    3880
                mstore(0x80, p3)
    3881
            }
    3882
            _sendLogPayload(0x1c, 0x84);
    3883
            /// @solidity memory-safe-assembly
    3884
            assembly {
    3885
                mstore(0x00, m0)
    3886
                mstore(0x20, m1)
    3887
                mstore(0x40, m2)
    3888
                mstore(0x60, m3)
    3889
                mstore(0x80, m4)
    3890
            }
    3891
        }
    3892
    3893
        function log(address p0, bool p1, uint256 p2, bool p3) internal pure {
    3894
            bytes32 m0;
    3895
            bytes32 m1;
    3896
            bytes32 m2;
    3897
            bytes32 m3;
    3898
            bytes32 m4;
    3899
            /// @solidity memory-safe-assembly
    3900
            assembly {
    3901
                m0 := mload(0x00)
    3902
                m1 := mload(0x20)
    3903
                m2 := mload(0x40)
    3904
                m3 := mload(0x60)
    3905
                m4 := mload(0x80)
    3906
                // Selector of `log(address,bool,uint256,bool)`.
    3907
                mstore(0x00, 0xc4643e20)
    3908
                mstore(0x20, p0)
    3909
                mstore(0x40, p1)
    3910
                mstore(0x60, p2)
    3911
                mstore(0x80, p3)
    3912
            }
    3913
            _sendLogPayload(0x1c, 0x84);
    3914
            /// @solidity memory-safe-assembly
    3915
            assembly {
    3916
                mstore(0x00, m0)
    3917
                mstore(0x20, m1)
    3918
                mstore(0x40, m2)
    3919
                mstore(0x60, m3)
    3920
                mstore(0x80, m4)
    3921
            }
    3922
        }
    3923
    3924
        function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure {
    3925
            bytes32 m0;
    3926
            bytes32 m1;
    3927
            bytes32 m2;
    3928
            bytes32 m3;
    3929
            bytes32 m4;
    3930
            /// @solidity memory-safe-assembly
    3931
            assembly {
    3932
                m0 := mload(0x00)
    3933
                m1 := mload(0x20)
    3934
                m2 := mload(0x40)
    3935
                m3 := mload(0x60)
    3936
                m4 := mload(0x80)
    3937
                // Selector of `log(address,bool,uint256,uint256)`.
    3938
                mstore(0x00, 0x386ff5f4)
    3939
                mstore(0x20, p0)
    3940
                mstore(0x40, p1)
    3941
                mstore(0x60, p2)
    3942
                mstore(0x80, p3)
    3943
            }
    3944
            _sendLogPayload(0x1c, 0x84);
    3945
            /// @solidity memory-safe-assembly
    3946
            assembly {
    3947
                mstore(0x00, m0)
    3948
                mstore(0x20, m1)
    3949
                mstore(0x40, m2)
    3950
                mstore(0x60, m3)
    3951
                mstore(0x80, m4)
    3952
            }
    3953
        }
    3954
    3955
        function log(address p0, bool p1, uint256 p2, bytes32 p3) internal pure {
    3956
            bytes32 m0;
    3957
            bytes32 m1;
    3958
            bytes32 m2;
    3959
            bytes32 m3;
    3960
            bytes32 m4;
    3961
            bytes32 m5;
    3962
            bytes32 m6;
    3963
            /// @solidity memory-safe-assembly
    3964
            assembly {
    3965
                function writeString(pos, w) {
    3966
                    let length := 0
    3967
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    3968
                    mstore(pos, length)
    3969
                    let shift := sub(256, shl(3, length))
    3970
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    3971
                }
    3972
                m0 := mload(0x00)
    3973
                m1 := mload(0x20)
    3974
                m2 := mload(0x40)
    3975
                m3 := mload(0x60)
    3976
                m4 := mload(0x80)
    3977
                m5 := mload(0xa0)
    3978
                m6 := mload(0xc0)
    3979
                // Selector of `log(address,bool,uint256,string)`.
    3980
                mstore(0x00, 0x0aa6cfad)
    3981
                mstore(0x20, p0)
    3982
                mstore(0x40, p1)
    3983
                mstore(0x60, p2)
    3984
                mstore(0x80, 0x80)
    3985
                writeString(0xa0, p3)
    3986
            }
    3987
            _sendLogPayload(0x1c, 0xc4);
    3988
            /// @solidity memory-safe-assembly
    3989
            assembly {
    3990
                mstore(0x00, m0)
    3991
                mstore(0x20, m1)
    3992
                mstore(0x40, m2)
    3993
                mstore(0x60, m3)
    3994
                mstore(0x80, m4)
    3995
                mstore(0xa0, m5)
    3996
                mstore(0xc0, m6)
    3997
            }
    3998
        }
    3999
    4000
        function log(address p0, bool p1, bytes32 p2, address p3) internal pure {
    4001
            bytes32 m0;
    4002
            bytes32 m1;
    4003
            bytes32 m2;
    4004
            bytes32 m3;
    4005
            bytes32 m4;
    4006
            bytes32 m5;
    4007
            bytes32 m6;
    4008
            /// @solidity memory-safe-assembly
    4009
            assembly {
    4010
                function writeString(pos, w) {
    4011
                    let length := 0
    4012
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    4013
                    mstore(pos, length)
    4014
                    let shift := sub(256, shl(3, length))
    4015
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    4016
                }
    4017
                m0 := mload(0x00)
    4018
                m1 := mload(0x20)
    4019
                m2 := mload(0x40)
    4020
                m3 := mload(0x60)
    4021
                m4 := mload(0x80)
    4022
                m5 := mload(0xa0)
    4023
                m6 := mload(0xc0)
    4024
                // Selector of `log(address,bool,string,address)`.
    4025
                mstore(0x00, 0x19fd4956)
    4026
                mstore(0x20, p0)
    4027
                mstore(0x40, p1)
    4028
                mstore(0x60, 0x80)
    4029
                mstore(0x80, p3)
    4030
                writeString(0xa0, p2)
    4031
            }
    4032
            _sendLogPayload(0x1c, 0xc4);
    4033
            /// @solidity memory-safe-assembly
    4034
            assembly {
    4035
                mstore(0x00, m0)
    4036
                mstore(0x20, m1)
    4037
                mstore(0x40, m2)
    4038
                mstore(0x60, m3)
    4039
                mstore(0x80, m4)
    4040
                mstore(0xa0, m5)
    4041
                mstore(0xc0, m6)
    4042
            }
    4043
        }
    4044
    4045
        function log(address p0, bool p1, bytes32 p2, bool p3) internal pure {
    4046
            bytes32 m0;
    4047
            bytes32 m1;
    4048
            bytes32 m2;
    4049
            bytes32 m3;
    4050
            bytes32 m4;
    4051
            bytes32 m5;
    4052
            bytes32 m6;
    4053
            /// @solidity memory-safe-assembly
    4054
            assembly {
    4055
                function writeString(pos, w) {
    4056
                    let length := 0
    4057
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    4058
                    mstore(pos, length)
    4059
                    let shift := sub(256, shl(3, length))
    4060
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    4061
                }
    4062
                m0 := mload(0x00)
    4063
                m1 := mload(0x20)
    4064
                m2 := mload(0x40)
    4065
                m3 := mload(0x60)
    4066
                m4 := mload(0x80)
    4067
                m5 := mload(0xa0)
    4068
                m6 := mload(0xc0)
    4069
                // Selector of `log(address,bool,string,bool)`.
    4070
                mstore(0x00, 0x50ad461d)
    4071
                mstore(0x20, p0)
    4072
                mstore(0x40, p1)
    4073
                mstore(0x60, 0x80)
    4074
                mstore(0x80, p3)
    4075
                writeString(0xa0, p2)
    4076
            }
    4077
            _sendLogPayload(0x1c, 0xc4);
    4078
            /// @solidity memory-safe-assembly
    4079
            assembly {
    4080
                mstore(0x00, m0)
    4081
                mstore(0x20, m1)
    4082
                mstore(0x40, m2)
    4083
                mstore(0x60, m3)
    4084
                mstore(0x80, m4)
    4085
                mstore(0xa0, m5)
    4086
                mstore(0xc0, m6)
    4087
            }
    4088
        }
    4089
    4090
        function log(address p0, bool p1, bytes32 p2, uint256 p3) internal pure {
    4091
            bytes32 m0;
    4092
            bytes32 m1;
    4093
            bytes32 m2;
    4094
            bytes32 m3;
    4095
            bytes32 m4;
    4096
            bytes32 m5;
    4097
            bytes32 m6;
    4098
            /// @solidity memory-safe-assembly
    4099
            assembly {
    4100
                function writeString(pos, w) {
    4101
                    let length := 0
    4102
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    4103
                    mstore(pos, length)
    4104
                    let shift := sub(256, shl(3, length))
    4105
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    4106
                }
    4107
                m0 := mload(0x00)
    4108
                m1 := mload(0x20)
    4109
                m2 := mload(0x40)
    4110
                m3 := mload(0x60)
    4111
                m4 := mload(0x80)
    4112
                m5 := mload(0xa0)
    4113
                m6 := mload(0xc0)
    4114
                // Selector of `log(address,bool,string,uint256)`.
    4115
                mstore(0x00, 0x80e6a20b)
    4116
                mstore(0x20, p0)
    4117
                mstore(0x40, p1)
    4118
                mstore(0x60, 0x80)
    4119
                mstore(0x80, p3)
    4120
                writeString(0xa0, p2)
    4121
            }
    4122
            _sendLogPayload(0x1c, 0xc4);
    4123
            /// @solidity memory-safe-assembly
    4124
            assembly {
    4125
                mstore(0x00, m0)
    4126
                mstore(0x20, m1)
    4127
                mstore(0x40, m2)
    4128
                mstore(0x60, m3)
    4129
                mstore(0x80, m4)
    4130
                mstore(0xa0, m5)
    4131
                mstore(0xc0, m6)
    4132
            }
    4133
        }
    4134
    4135
        function log(address p0, bool p1, bytes32 p2, bytes32 p3) internal pure {
    4136
            bytes32 m0;
    4137
            bytes32 m1;
    4138
            bytes32 m2;
    4139
            bytes32 m3;
    4140
            bytes32 m4;
    4141
            bytes32 m5;
    4142
            bytes32 m6;
    4143
            bytes32 m7;
    4144
            bytes32 m8;
    4145
            /// @solidity memory-safe-assembly
    4146
            assembly {
    4147
                function writeString(pos, w) {
    4148
                    let length := 0
    4149
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    4150
                    mstore(pos, length)
    4151
                    let shift := sub(256, shl(3, length))
    4152
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    4153
                }
    4154
                m0 := mload(0x00)
    4155
                m1 := mload(0x20)
    4156
                m2 := mload(0x40)
    4157
                m3 := mload(0x60)
    4158
                m4 := mload(0x80)
    4159
                m5 := mload(0xa0)
    4160
                m6 := mload(0xc0)
    4161
                m7 := mload(0xe0)
    4162
                m8 := mload(0x100)
    4163
                // Selector of `log(address,bool,string,string)`.
    4164
                mstore(0x00, 0x475c5c33)
    4165
                mstore(0x20, p0)
    4166
                mstore(0x40, p1)
    4167
                mstore(0x60, 0x80)
    4168
                mstore(0x80, 0xc0)
    4169
                writeString(0xa0, p2)
    4170
                writeString(0xe0, p3)
    4171
            }
    4172
            _sendLogPayload(0x1c, 0x104);
    4173
            /// @solidity memory-safe-assembly
    4174
            assembly {
    4175
                mstore(0x00, m0)
    4176
                mstore(0x20, m1)
    4177
                mstore(0x40, m2)
    4178
                mstore(0x60, m3)
    4179
                mstore(0x80, m4)
    4180
                mstore(0xa0, m5)
    4181
                mstore(0xc0, m6)
    4182
                mstore(0xe0, m7)
    4183
                mstore(0x100, m8)
    4184
            }
    4185
        }
    4186
    4187
        function log(address p0, uint256 p1, address p2, address p3) internal pure {
    4188
            bytes32 m0;
    4189
            bytes32 m1;
    4190
            bytes32 m2;
    4191
            bytes32 m3;
    4192
            bytes32 m4;
    4193
            /// @solidity memory-safe-assembly
    4194
            assembly {
    4195
                m0 := mload(0x00)
    4196
                m1 := mload(0x20)
    4197
                m2 := mload(0x40)
    4198
                m3 := mload(0x60)
    4199
                m4 := mload(0x80)
    4200
                // Selector of `log(address,uint256,address,address)`.
    4201
                mstore(0x00, 0x478d1c62)
    4202
                mstore(0x20, p0)
    4203
                mstore(0x40, p1)
    4204
                mstore(0x60, p2)
    4205
                mstore(0x80, p3)
    4206
            }
    4207
            _sendLogPayload(0x1c, 0x84);
    4208
            /// @solidity memory-safe-assembly
    4209
            assembly {
    4210
                mstore(0x00, m0)
    4211
                mstore(0x20, m1)
    4212
                mstore(0x40, m2)
    4213
                mstore(0x60, m3)
    4214
                mstore(0x80, m4)
    4215
            }
    4216
        }
    4217
    4218
        function log(address p0, uint256 p1, address p2, bool p3) internal pure {
    4219
            bytes32 m0;
    4220
            bytes32 m1;
    4221
            bytes32 m2;
    4222
            bytes32 m3;
    4223
            bytes32 m4;
    4224
            /// @solidity memory-safe-assembly
    4225
            assembly {
    4226
                m0 := mload(0x00)
    4227
                m1 := mload(0x20)
    4228
                m2 := mload(0x40)
    4229
                m3 := mload(0x60)
    4230
                m4 := mload(0x80)
    4231
                // Selector of `log(address,uint256,address,bool)`.
    4232
                mstore(0x00, 0xa1bcc9b3)
    4233
                mstore(0x20, p0)
    4234
                mstore(0x40, p1)
    4235
                mstore(0x60, p2)
    4236
                mstore(0x80, p3)
    4237
            }
    4238
            _sendLogPayload(0x1c, 0x84);
    4239
            /// @solidity memory-safe-assembly
    4240
            assembly {
    4241
                mstore(0x00, m0)
    4242
                mstore(0x20, m1)
    4243
                mstore(0x40, m2)
    4244
                mstore(0x60, m3)
    4245
                mstore(0x80, m4)
    4246
            }
    4247
        }
    4248
    4249
        function log(address p0, uint256 p1, address p2, uint256 p3) internal pure {
    4250
            bytes32 m0;
    4251
            bytes32 m1;
    4252
            bytes32 m2;
    4253
            bytes32 m3;
    4254
            bytes32 m4;
    4255
            /// @solidity memory-safe-assembly
    4256
            assembly {
    4257
                m0 := mload(0x00)
    4258
                m1 := mload(0x20)
    4259
                m2 := mload(0x40)
    4260
                m3 := mload(0x60)
    4261
                m4 := mload(0x80)
    4262
                // Selector of `log(address,uint256,address,uint256)`.
    4263
                mstore(0x00, 0x100f650e)
    4264
                mstore(0x20, p0)
    4265
                mstore(0x40, p1)
    4266
                mstore(0x60, p2)
    4267
                mstore(0x80, p3)
    4268
            }
    4269
            _sendLogPayload(0x1c, 0x84);
    4270
            /// @solidity memory-safe-assembly
    4271
            assembly {
    4272
                mstore(0x00, m0)
    4273
                mstore(0x20, m1)
    4274
                mstore(0x40, m2)
    4275
                mstore(0x60, m3)
    4276
                mstore(0x80, m4)
    4277
            }
    4278
        }
    4279
    4280
        function log(address p0, uint256 p1, address p2, bytes32 p3) internal pure {
    4281
            bytes32 m0;
    4282
            bytes32 m1;
    4283
            bytes32 m2;
    4284
            bytes32 m3;
    4285
            bytes32 m4;
    4286
            bytes32 m5;
    4287
            bytes32 m6;
    4288
            /// @solidity memory-safe-assembly
    4289
            assembly {
    4290
                function writeString(pos, w) {
    4291
                    let length := 0
    4292
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    4293
                    mstore(pos, length)
    4294
                    let shift := sub(256, shl(3, length))
    4295
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    4296
                }
    4297
                m0 := mload(0x00)
    4298
                m1 := mload(0x20)
    4299
                m2 := mload(0x40)
    4300
                m3 := mload(0x60)
    4301
                m4 := mload(0x80)
    4302
                m5 := mload(0xa0)
    4303
                m6 := mload(0xc0)
    4304
                // Selector of `log(address,uint256,address,string)`.
    4305
                mstore(0x00, 0x1da986ea)
    4306
                mstore(0x20, p0)
    4307
                mstore(0x40, p1)
    4308
                mstore(0x60, p2)
    4309
                mstore(0x80, 0x80)
    4310
                writeString(0xa0, p3)
    4311
            }
    4312
            _sendLogPayload(0x1c, 0xc4);
    4313
            /// @solidity memory-safe-assembly
    4314
            assembly {
    4315
                mstore(0x00, m0)
    4316
                mstore(0x20, m1)
    4317
                mstore(0x40, m2)
    4318
                mstore(0x60, m3)
    4319
                mstore(0x80, m4)
    4320
                mstore(0xa0, m5)
    4321
                mstore(0xc0, m6)
    4322
            }
    4323
        }
    4324
    4325
        function log(address p0, uint256 p1, bool p2, address p3) internal pure {
    4326
            bytes32 m0;
    4327
            bytes32 m1;
    4328
            bytes32 m2;
    4329
            bytes32 m3;
    4330
            bytes32 m4;
    4331
            /// @solidity memory-safe-assembly
    4332
            assembly {
    4333
                m0 := mload(0x00)
    4334
                m1 := mload(0x20)
    4335
                m2 := mload(0x40)
    4336
                m3 := mload(0x60)
    4337
                m4 := mload(0x80)
    4338
                // Selector of `log(address,uint256,bool,address)`.
    4339
                mstore(0x00, 0xa31bfdcc)
    4340
                mstore(0x20, p0)
    4341
                mstore(0x40, p1)
    4342
                mstore(0x60, p2)
    4343
                mstore(0x80, p3)
    4344
            }
    4345
            _sendLogPayload(0x1c, 0x84);
    4346
            /// @solidity memory-safe-assembly
    4347
            assembly {
    4348
                mstore(0x00, m0)
    4349
                mstore(0x20, m1)
    4350
                mstore(0x40, m2)
    4351
                mstore(0x60, m3)
    4352
                mstore(0x80, m4)
    4353
            }
    4354
        }
    4355
    4356
        function log(address p0, uint256 p1, bool p2, bool p3) internal pure {
    4357
            bytes32 m0;
    4358
            bytes32 m1;
    4359
            bytes32 m2;
    4360
            bytes32 m3;
    4361
            bytes32 m4;
    4362
            /// @solidity memory-safe-assembly
    4363
            assembly {
    4364
                m0 := mload(0x00)
    4365
                m1 := mload(0x20)
    4366
                m2 := mload(0x40)
    4367
                m3 := mload(0x60)
    4368
                m4 := mload(0x80)
    4369
                // Selector of `log(address,uint256,bool,bool)`.
    4370
                mstore(0x00, 0x3bf5e537)
    4371
                mstore(0x20, p0)
    4372
                mstore(0x40, p1)
    4373
                mstore(0x60, p2)
    4374
                mstore(0x80, p3)
    4375
            }
    4376
            _sendLogPayload(0x1c, 0x84);
    4377
            /// @solidity memory-safe-assembly
    4378
            assembly {
    4379
                mstore(0x00, m0)
    4380
                mstore(0x20, m1)
    4381
                mstore(0x40, m2)
    4382
                mstore(0x60, m3)
    4383
                mstore(0x80, m4)
    4384
            }
    4385
        }
    4386
    4387
        function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure {
    4388
            bytes32 m0;
    4389
            bytes32 m1;
    4390
            bytes32 m2;
    4391
            bytes32 m3;
    4392
            bytes32 m4;
    4393
            /// @solidity memory-safe-assembly
    4394
            assembly {
    4395
                m0 := mload(0x00)
    4396
                m1 := mload(0x20)
    4397
                m2 := mload(0x40)
    4398
                m3 := mload(0x60)
    4399
                m4 := mload(0x80)
    4400
                // Selector of `log(address,uint256,bool,uint256)`.
    4401
                mstore(0x00, 0x22f6b999)
    4402
                mstore(0x20, p0)
    4403
                mstore(0x40, p1)
    4404
                mstore(0x60, p2)
    4405
                mstore(0x80, p3)
    4406
            }
    4407
            _sendLogPayload(0x1c, 0x84);
    4408
            /// @solidity memory-safe-assembly
    4409
            assembly {
    4410
                mstore(0x00, m0)
    4411
                mstore(0x20, m1)
    4412
                mstore(0x40, m2)
    4413
                mstore(0x60, m3)
    4414
                mstore(0x80, m4)
    4415
            }
    4416
        }
    4417
    4418
        function log(address p0, uint256 p1, bool p2, bytes32 p3) internal pure {
    4419
            bytes32 m0;
    4420
            bytes32 m1;
    4421
            bytes32 m2;
    4422
            bytes32 m3;
    4423
            bytes32 m4;
    4424
            bytes32 m5;
    4425
            bytes32 m6;
    4426
            /// @solidity memory-safe-assembly
    4427
            assembly {
    4428
                function writeString(pos, w) {
    4429
                    let length := 0
    4430
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    4431
                    mstore(pos, length)
    4432
                    let shift := sub(256, shl(3, length))
    4433
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    4434
                }
    4435
                m0 := mload(0x00)
    4436
                m1 := mload(0x20)
    4437
                m2 := mload(0x40)
    4438
                m3 := mload(0x60)
    4439
                m4 := mload(0x80)
    4440
                m5 := mload(0xa0)
    4441
                m6 := mload(0xc0)
    4442
                // Selector of `log(address,uint256,bool,string)`.
    4443
                mstore(0x00, 0xc5ad85f9)
    4444
                mstore(0x20, p0)
    4445
                mstore(0x40, p1)
    4446
                mstore(0x60, p2)
    4447
                mstore(0x80, 0x80)
    4448
                writeString(0xa0, p3)
    4449
            }
    4450
            _sendLogPayload(0x1c, 0xc4);
    4451
            /// @solidity memory-safe-assembly
    4452
            assembly {
    4453
                mstore(0x00, m0)
    4454
                mstore(0x20, m1)
    4455
                mstore(0x40, m2)
    4456
                mstore(0x60, m3)
    4457
                mstore(0x80, m4)
    4458
                mstore(0xa0, m5)
    4459
                mstore(0xc0, m6)
    4460
            }
    4461
        }
    4462
    4463
        function log(address p0, uint256 p1, uint256 p2, address p3) internal pure {
    4464
            bytes32 m0;
    4465
            bytes32 m1;
    4466
            bytes32 m2;
    4467
            bytes32 m3;
    4468
            bytes32 m4;
    4469
            /// @solidity memory-safe-assembly
    4470
            assembly {
    4471
                m0 := mload(0x00)
    4472
                m1 := mload(0x20)
    4473
                m2 := mload(0x40)
    4474
                m3 := mload(0x60)
    4475
                m4 := mload(0x80)
    4476
                // Selector of `log(address,uint256,uint256,address)`.
    4477
                mstore(0x00, 0x20e3984d)
    4478
                mstore(0x20, p0)
    4479
                mstore(0x40, p1)
    4480
                mstore(0x60, p2)
    4481
                mstore(0x80, p3)
    4482
            }
    4483
            _sendLogPayload(0x1c, 0x84);
    4484
            /// @solidity memory-safe-assembly
    4485
            assembly {
    4486
                mstore(0x00, m0)
    4487
                mstore(0x20, m1)
    4488
                mstore(0x40, m2)
    4489
                mstore(0x60, m3)
    4490
                mstore(0x80, m4)
    4491
            }
    4492
        }
    4493
    4494
        function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure {
    4495
            bytes32 m0;
    4496
            bytes32 m1;
    4497
            bytes32 m2;
    4498
            bytes32 m3;
    4499
            bytes32 m4;
    4500
            /// @solidity memory-safe-assembly
    4501
            assembly {
    4502
                m0 := mload(0x00)
    4503
                m1 := mload(0x20)
    4504
                m2 := mload(0x40)
    4505
                m3 := mload(0x60)
    4506
                m4 := mload(0x80)
    4507
                // Selector of `log(address,uint256,uint256,bool)`.
    4508
                mstore(0x00, 0x66f1bc67)
    4509
                mstore(0x20, p0)
    4510
                mstore(0x40, p1)
    4511
                mstore(0x60, p2)
    4512
                mstore(0x80, p3)
    4513
            }
    4514
            _sendLogPayload(0x1c, 0x84);
    4515
            /// @solidity memory-safe-assembly
    4516
            assembly {
    4517
                mstore(0x00, m0)
    4518
                mstore(0x20, m1)
    4519
                mstore(0x40, m2)
    4520
                mstore(0x60, m3)
    4521
                mstore(0x80, m4)
    4522
            }
    4523
        }
    4524
    4525
        function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
    4526
            bytes32 m0;
    4527
            bytes32 m1;
    4528
            bytes32 m2;
    4529
            bytes32 m3;
    4530
            bytes32 m4;
    4531
            /// @solidity memory-safe-assembly
    4532
            assembly {
    4533
                m0 := mload(0x00)
    4534
                m1 := mload(0x20)
    4535
                m2 := mload(0x40)
    4536
                m3 := mload(0x60)
    4537
                m4 := mload(0x80)
    4538
                // Selector of `log(address,uint256,uint256,uint256)`.
    4539
                mstore(0x00, 0x34f0e636)
    4540
                mstore(0x20, p0)
    4541
                mstore(0x40, p1)
    4542
                mstore(0x60, p2)
    4543
                mstore(0x80, p3)
    4544
            }
    4545
            _sendLogPayload(0x1c, 0x84);
    4546
            /// @solidity memory-safe-assembly
    4547
            assembly {
    4548
                mstore(0x00, m0)
    4549
                mstore(0x20, m1)
    4550
                mstore(0x40, m2)
    4551
                mstore(0x60, m3)
    4552
                mstore(0x80, m4)
    4553
            }
    4554
        }
    4555
    4556
        function log(address p0, uint256 p1, uint256 p2, bytes32 p3) internal pure {
    4557
            bytes32 m0;
    4558
            bytes32 m1;
    4559
            bytes32 m2;
    4560
            bytes32 m3;
    4561
            bytes32 m4;
    4562
            bytes32 m5;
    4563
            bytes32 m6;
    4564
            /// @solidity memory-safe-assembly
    4565
            assembly {
    4566
                function writeString(pos, w) {
    4567
                    let length := 0
    4568
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    4569
                    mstore(pos, length)
    4570
                    let shift := sub(256, shl(3, length))
    4571
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    4572
                }
    4573
                m0 := mload(0x00)
    4574
                m1 := mload(0x20)
    4575
                m2 := mload(0x40)
    4576
                m3 := mload(0x60)
    4577
                m4 := mload(0x80)
    4578
                m5 := mload(0xa0)
    4579
                m6 := mload(0xc0)
    4580
                // Selector of `log(address,uint256,uint256,string)`.
    4581
                mstore(0x00, 0x4a28c017)
    4582
                mstore(0x20, p0)
    4583
                mstore(0x40, p1)
    4584
                mstore(0x60, p2)
    4585
                mstore(0x80, 0x80)
    4586
                writeString(0xa0, p3)
    4587
            }
    4588
            _sendLogPayload(0x1c, 0xc4);
    4589
            /// @solidity memory-safe-assembly
    4590
            assembly {
    4591
                mstore(0x00, m0)
    4592
                mstore(0x20, m1)
    4593
                mstore(0x40, m2)
    4594
                mstore(0x60, m3)
    4595
                mstore(0x80, m4)
    4596
                mstore(0xa0, m5)
    4597
                mstore(0xc0, m6)
    4598
            }
    4599
        }
    4600
    4601
        function log(address p0, uint256 p1, bytes32 p2, address p3) internal pure {
    4602
            bytes32 m0;
    4603
            bytes32 m1;
    4604
            bytes32 m2;
    4605
            bytes32 m3;
    4606
            bytes32 m4;
    4607
            bytes32 m5;
    4608
            bytes32 m6;
    4609
            /// @solidity memory-safe-assembly
    4610
            assembly {
    4611
                function writeString(pos, w) {
    4612
                    let length := 0
    4613
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    4614
                    mstore(pos, length)
    4615
                    let shift := sub(256, shl(3, length))
    4616
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    4617
                }
    4618
                m0 := mload(0x00)
    4619
                m1 := mload(0x20)
    4620
                m2 := mload(0x40)
    4621
                m3 := mload(0x60)
    4622
                m4 := mload(0x80)
    4623
                m5 := mload(0xa0)
    4624
                m6 := mload(0xc0)
    4625
                // Selector of `log(address,uint256,string,address)`.
    4626
                mstore(0x00, 0x5c430d47)
    4627
                mstore(0x20, p0)
    4628
                mstore(0x40, p1)
    4629
                mstore(0x60, 0x80)
    4630
                mstore(0x80, p3)
    4631
                writeString(0xa0, p2)
    4632
            }
    4633
            _sendLogPayload(0x1c, 0xc4);
    4634
            /// @solidity memory-safe-assembly
    4635
            assembly {
    4636
                mstore(0x00, m0)
    4637
                mstore(0x20, m1)
    4638
                mstore(0x40, m2)
    4639
                mstore(0x60, m3)
    4640
                mstore(0x80, m4)
    4641
                mstore(0xa0, m5)
    4642
                mstore(0xc0, m6)
    4643
            }
    4644
        }
    4645
    4646
        function log(address p0, uint256 p1, bytes32 p2, bool p3) internal pure {
    4647
            bytes32 m0;
    4648
            bytes32 m1;
    4649
            bytes32 m2;
    4650
            bytes32 m3;
    4651
            bytes32 m4;
    4652
            bytes32 m5;
    4653
            bytes32 m6;
    4654
            /// @solidity memory-safe-assembly
    4655
            assembly {
    4656
                function writeString(pos, w) {
    4657
                    let length := 0
    4658
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    4659
                    mstore(pos, length)
    4660
                    let shift := sub(256, shl(3, length))
    4661
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    4662
                }
    4663
                m0 := mload(0x00)
    4664
                m1 := mload(0x20)
    4665
                m2 := mload(0x40)
    4666
                m3 := mload(0x60)
    4667
                m4 := mload(0x80)
    4668
                m5 := mload(0xa0)
    4669
                m6 := mload(0xc0)
    4670
                // Selector of `log(address,uint256,string,bool)`.
    4671
                mstore(0x00, 0xcf18105c)
    4672
                mstore(0x20, p0)
    4673
                mstore(0x40, p1)
    4674
                mstore(0x60, 0x80)
    4675
                mstore(0x80, p3)
    4676
                writeString(0xa0, p2)
    4677
            }
    4678
            _sendLogPayload(0x1c, 0xc4);
    4679
            /// @solidity memory-safe-assembly
    4680
            assembly {
    4681
                mstore(0x00, m0)
    4682
                mstore(0x20, m1)
    4683
                mstore(0x40, m2)
    4684
                mstore(0x60, m3)
    4685
                mstore(0x80, m4)
    4686
                mstore(0xa0, m5)
    4687
                mstore(0xc0, m6)
    4688
            }
    4689
        }
    4690
    4691
        function log(address p0, uint256 p1, bytes32 p2, uint256 p3) internal pure {
    4692
            bytes32 m0;
    4693
            bytes32 m1;
    4694
            bytes32 m2;
    4695
            bytes32 m3;
    4696
            bytes32 m4;
    4697
            bytes32 m5;
    4698
            bytes32 m6;
    4699
            /// @solidity memory-safe-assembly
    4700
            assembly {
    4701
                function writeString(pos, w) {
    4702
                    let length := 0
    4703
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    4704
                    mstore(pos, length)
    4705
                    let shift := sub(256, shl(3, length))
    4706
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    4707
                }
    4708
                m0 := mload(0x00)
    4709
                m1 := mload(0x20)
    4710
                m2 := mload(0x40)
    4711
                m3 := mload(0x60)
    4712
                m4 := mload(0x80)
    4713
                m5 := mload(0xa0)
    4714
                m6 := mload(0xc0)
    4715
                // Selector of `log(address,uint256,string,uint256)`.
    4716
                mstore(0x00, 0xbf01f891)
    4717
                mstore(0x20, p0)
    4718
                mstore(0x40, p1)
    4719
                mstore(0x60, 0x80)
    4720
                mstore(0x80, p3)
    4721
                writeString(0xa0, p2)
    4722
            }
    4723
            _sendLogPayload(0x1c, 0xc4);
    4724
            /// @solidity memory-safe-assembly
    4725
            assembly {
    4726
                mstore(0x00, m0)
    4727
                mstore(0x20, m1)
    4728
                mstore(0x40, m2)
    4729
                mstore(0x60, m3)
    4730
                mstore(0x80, m4)
    4731
                mstore(0xa0, m5)
    4732
                mstore(0xc0, m6)
    4733
            }
    4734
        }
    4735
    4736
        function log(address p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure {
    4737
            bytes32 m0;
    4738
            bytes32 m1;
    4739
            bytes32 m2;
    4740
            bytes32 m3;
    4741
            bytes32 m4;
    4742
            bytes32 m5;
    4743
            bytes32 m6;
    4744
            bytes32 m7;
    4745
            bytes32 m8;
    4746
            /// @solidity memory-safe-assembly
    4747
            assembly {
    4748
                function writeString(pos, w) {
    4749
                    let length := 0
    4750
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    4751
                    mstore(pos, length)
    4752
                    let shift := sub(256, shl(3, length))
    4753
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    4754
                }
    4755
                m0 := mload(0x00)
    4756
                m1 := mload(0x20)
    4757
                m2 := mload(0x40)
    4758
                m3 := mload(0x60)
    4759
                m4 := mload(0x80)
    4760
                m5 := mload(0xa0)
    4761
                m6 := mload(0xc0)
    4762
                m7 := mload(0xe0)
    4763
                m8 := mload(0x100)
    4764
                // Selector of `log(address,uint256,string,string)`.
    4765
                mstore(0x00, 0x88a8c406)
    4766
                mstore(0x20, p0)
    4767
                mstore(0x40, p1)
    4768
                mstore(0x60, 0x80)
    4769
                mstore(0x80, 0xc0)
    4770
                writeString(0xa0, p2)
    4771
                writeString(0xe0, p3)
    4772
            }
    4773
            _sendLogPayload(0x1c, 0x104);
    4774
            /// @solidity memory-safe-assembly
    4775
            assembly {
    4776
                mstore(0x00, m0)
    4777
                mstore(0x20, m1)
    4778
                mstore(0x40, m2)
    4779
                mstore(0x60, m3)
    4780
                mstore(0x80, m4)
    4781
                mstore(0xa0, m5)
    4782
                mstore(0xc0, m6)
    4783
                mstore(0xe0, m7)
    4784
                mstore(0x100, m8)
    4785
            }
    4786
        }
    4787
    4788
        function log(address p0, bytes32 p1, address p2, address p3) internal pure {
    4789
            bytes32 m0;
    4790
            bytes32 m1;
    4791
            bytes32 m2;
    4792
            bytes32 m3;
    4793
            bytes32 m4;
    4794
            bytes32 m5;
    4795
            bytes32 m6;
    4796
            /// @solidity memory-safe-assembly
    4797
            assembly {
    4798
                function writeString(pos, w) {
    4799
                    let length := 0
    4800
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    4801
                    mstore(pos, length)
    4802
                    let shift := sub(256, shl(3, length))
    4803
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    4804
                }
    4805
                m0 := mload(0x00)
    4806
                m1 := mload(0x20)
    4807
                m2 := mload(0x40)
    4808
                m3 := mload(0x60)
    4809
                m4 := mload(0x80)
    4810
                m5 := mload(0xa0)
    4811
                m6 := mload(0xc0)
    4812
                // Selector of `log(address,string,address,address)`.
    4813
                mstore(0x00, 0x0d36fa20)
    4814
                mstore(0x20, p0)
    4815
                mstore(0x40, 0x80)
    4816
                mstore(0x60, p2)
    4817
                mstore(0x80, p3)
    4818
                writeString(0xa0, p1)
    4819
            }
    4820
            _sendLogPayload(0x1c, 0xc4);
    4821
            /// @solidity memory-safe-assembly
    4822
            assembly {
    4823
                mstore(0x00, m0)
    4824
                mstore(0x20, m1)
    4825
                mstore(0x40, m2)
    4826
                mstore(0x60, m3)
    4827
                mstore(0x80, m4)
    4828
                mstore(0xa0, m5)
    4829
                mstore(0xc0, m6)
    4830
            }
    4831
        }
    4832
    4833
        function log(address p0, bytes32 p1, address p2, bool p3) internal pure {
    4834
            bytes32 m0;
    4835
            bytes32 m1;
    4836
            bytes32 m2;
    4837
            bytes32 m3;
    4838
            bytes32 m4;
    4839
            bytes32 m5;
    4840
            bytes32 m6;
    4841
            /// @solidity memory-safe-assembly
    4842
            assembly {
    4843
                function writeString(pos, w) {
    4844
                    let length := 0
    4845
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    4846
                    mstore(pos, length)
    4847
                    let shift := sub(256, shl(3, length))
    4848
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    4849
                }
    4850
                m0 := mload(0x00)
    4851
                m1 := mload(0x20)
    4852
                m2 := mload(0x40)
    4853
                m3 := mload(0x60)
    4854
                m4 := mload(0x80)
    4855
                m5 := mload(0xa0)
    4856
                m6 := mload(0xc0)
    4857
                // Selector of `log(address,string,address,bool)`.
    4858
                mstore(0x00, 0x0df12b76)
    4859
                mstore(0x20, p0)
    4860
                mstore(0x40, 0x80)
    4861
                mstore(0x60, p2)
    4862
                mstore(0x80, p3)
    4863
                writeString(0xa0, p1)
    4864
            }
    4865
            _sendLogPayload(0x1c, 0xc4);
    4866
            /// @solidity memory-safe-assembly
    4867
            assembly {
    4868
                mstore(0x00, m0)
    4869
                mstore(0x20, m1)
    4870
                mstore(0x40, m2)
    4871
                mstore(0x60, m3)
    4872
                mstore(0x80, m4)
    4873
                mstore(0xa0, m5)
    4874
                mstore(0xc0, m6)
    4875
            }
    4876
        }
    4877
    4878
        function log(address p0, bytes32 p1, address p2, uint256 p3) internal pure {
    4879
            bytes32 m0;
    4880
            bytes32 m1;
    4881
            bytes32 m2;
    4882
            bytes32 m3;
    4883
            bytes32 m4;
    4884
            bytes32 m5;
    4885
            bytes32 m6;
    4886
            /// @solidity memory-safe-assembly
    4887
            assembly {
    4888
                function writeString(pos, w) {
    4889
                    let length := 0
    4890
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    4891
                    mstore(pos, length)
    4892
                    let shift := sub(256, shl(3, length))
    4893
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    4894
                }
    4895
                m0 := mload(0x00)
    4896
                m1 := mload(0x20)
    4897
                m2 := mload(0x40)
    4898
                m3 := mload(0x60)
    4899
                m4 := mload(0x80)
    4900
                m5 := mload(0xa0)
    4901
                m6 := mload(0xc0)
    4902
                // Selector of `log(address,string,address,uint256)`.
    4903
                mstore(0x00, 0x457fe3cf)
    4904
                mstore(0x20, p0)
    4905
                mstore(0x40, 0x80)
    4906
                mstore(0x60, p2)
    4907
                mstore(0x80, p3)
    4908
                writeString(0xa0, p1)
    4909
            }
    4910
            _sendLogPayload(0x1c, 0xc4);
    4911
            /// @solidity memory-safe-assembly
    4912
            assembly {
    4913
                mstore(0x00, m0)
    4914
                mstore(0x20, m1)
    4915
                mstore(0x40, m2)
    4916
                mstore(0x60, m3)
    4917
                mstore(0x80, m4)
    4918
                mstore(0xa0, m5)
    4919
                mstore(0xc0, m6)
    4920
            }
    4921
        }
    4922
    4923
        function log(address p0, bytes32 p1, address p2, bytes32 p3) internal pure {
    4924
            bytes32 m0;
    4925
            bytes32 m1;
    4926
            bytes32 m2;
    4927
            bytes32 m3;
    4928
            bytes32 m4;
    4929
            bytes32 m5;
    4930
            bytes32 m6;
    4931
            bytes32 m7;
    4932
            bytes32 m8;
    4933
            /// @solidity memory-safe-assembly
    4934
            assembly {
    4935
                function writeString(pos, w) {
    4936
                    let length := 0
    4937
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    4938
                    mstore(pos, length)
    4939
                    let shift := sub(256, shl(3, length))
    4940
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    4941
                }
    4942
                m0 := mload(0x00)
    4943
                m1 := mload(0x20)
    4944
                m2 := mload(0x40)
    4945
                m3 := mload(0x60)
    4946
                m4 := mload(0x80)
    4947
                m5 := mload(0xa0)
    4948
                m6 := mload(0xc0)
    4949
                m7 := mload(0xe0)
    4950
                m8 := mload(0x100)
    4951
                // Selector of `log(address,string,address,string)`.
    4952
                mstore(0x00, 0xf7e36245)
    4953
                mstore(0x20, p0)
    4954
                mstore(0x40, 0x80)
    4955
                mstore(0x60, p2)
    4956
                mstore(0x80, 0xc0)
    4957
                writeString(0xa0, p1)
    4958
                writeString(0xe0, p3)
    4959
            }
    4960
            _sendLogPayload(0x1c, 0x104);
    4961
            /// @solidity memory-safe-assembly
    4962
            assembly {
    4963
                mstore(0x00, m0)
    4964
                mstore(0x20, m1)
    4965
                mstore(0x40, m2)
    4966
                mstore(0x60, m3)
    4967
                mstore(0x80, m4)
    4968
                mstore(0xa0, m5)
    4969
                mstore(0xc0, m6)
    4970
                mstore(0xe0, m7)
    4971
                mstore(0x100, m8)
    4972
            }
    4973
        }
    4974
    4975
        function log(address p0, bytes32 p1, bool p2, address p3) internal pure {
    4976
            bytes32 m0;
    4977
            bytes32 m1;
    4978
            bytes32 m2;
    4979
            bytes32 m3;
    4980
            bytes32 m4;
    4981
            bytes32 m5;
    4982
            bytes32 m6;
    4983
            /// @solidity memory-safe-assembly
    4984
            assembly {
    4985
                function writeString(pos, w) {
    4986
                    let length := 0
    4987
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    4988
                    mstore(pos, length)
    4989
                    let shift := sub(256, shl(3, length))
    4990
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    4991
                }
    4992
                m0 := mload(0x00)
    4993
                m1 := mload(0x20)
    4994
                m2 := mload(0x40)
    4995
                m3 := mload(0x60)
    4996
                m4 := mload(0x80)
    4997
                m5 := mload(0xa0)
    4998
                m6 := mload(0xc0)
    4999
                // Selector of `log(address,string,bool,address)`.
    5000
                mstore(0x00, 0x205871c2)
    5001
                mstore(0x20, p0)
    5002
                mstore(0x40, 0x80)
    5003
                mstore(0x60, p2)
    5004
                mstore(0x80, p3)
    5005
                writeString(0xa0, p1)
    5006
            }
    5007
            _sendLogPayload(0x1c, 0xc4);
    5008
            /// @solidity memory-safe-assembly
    5009
            assembly {
    5010
                mstore(0x00, m0)
    5011
                mstore(0x20, m1)
    5012
                mstore(0x40, m2)
    5013
                mstore(0x60, m3)
    5014
                mstore(0x80, m4)
    5015
                mstore(0xa0, m5)
    5016
                mstore(0xc0, m6)
    5017
            }
    5018
        }
    5019
    5020
        function log(address p0, bytes32 p1, bool p2, bool p3) internal pure {
    5021
            bytes32 m0;
    5022
            bytes32 m1;
    5023
            bytes32 m2;
    5024
            bytes32 m3;
    5025
            bytes32 m4;
    5026
            bytes32 m5;
    5027
            bytes32 m6;
    5028
            /// @solidity memory-safe-assembly
    5029
            assembly {
    5030
                function writeString(pos, w) {
    5031
                    let length := 0
    5032
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    5033
                    mstore(pos, length)
    5034
                    let shift := sub(256, shl(3, length))
    5035
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    5036
                }
    5037
                m0 := mload(0x00)
    5038
                m1 := mload(0x20)
    5039
                m2 := mload(0x40)
    5040
                m3 := mload(0x60)
    5041
                m4 := mload(0x80)
    5042
                m5 := mload(0xa0)
    5043
                m6 := mload(0xc0)
    5044
                // Selector of `log(address,string,bool,bool)`.
    5045
                mstore(0x00, 0x5f1d5c9f)
    5046
                mstore(0x20, p0)
    5047
                mstore(0x40, 0x80)
    5048
                mstore(0x60, p2)
    5049
                mstore(0x80, p3)
    5050
                writeString(0xa0, p1)
    5051
            }
    5052
            _sendLogPayload(0x1c, 0xc4);
    5053
            /// @solidity memory-safe-assembly
    5054
            assembly {
    5055
                mstore(0x00, m0)
    5056
                mstore(0x20, m1)
    5057
                mstore(0x40, m2)
    5058
                mstore(0x60, m3)
    5059
                mstore(0x80, m4)
    5060
                mstore(0xa0, m5)
    5061
                mstore(0xc0, m6)
    5062
            }
    5063
        }
    5064
    5065
        function log(address p0, bytes32 p1, bool p2, uint256 p3) internal pure {
    5066
            bytes32 m0;
    5067
            bytes32 m1;
    5068
            bytes32 m2;
    5069
            bytes32 m3;
    5070
            bytes32 m4;
    5071
            bytes32 m5;
    5072
            bytes32 m6;
    5073
            /// @solidity memory-safe-assembly
    5074
            assembly {
    5075
                function writeString(pos, w) {
    5076
                    let length := 0
    5077
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    5078
                    mstore(pos, length)
    5079
                    let shift := sub(256, shl(3, length))
    5080
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    5081
                }
    5082
                m0 := mload(0x00)
    5083
                m1 := mload(0x20)
    5084
                m2 := mload(0x40)
    5085
                m3 := mload(0x60)
    5086
                m4 := mload(0x80)
    5087
                m5 := mload(0xa0)
    5088
                m6 := mload(0xc0)
    5089
                // Selector of `log(address,string,bool,uint256)`.
    5090
                mstore(0x00, 0x515e38b6)
    5091
                mstore(0x20, p0)
    5092
                mstore(0x40, 0x80)
    5093
                mstore(0x60, p2)
    5094
                mstore(0x80, p3)
    5095
                writeString(0xa0, p1)
    5096
            }
    5097
            _sendLogPayload(0x1c, 0xc4);
    5098
            /// @solidity memory-safe-assembly
    5099
            assembly {
    5100
                mstore(0x00, m0)
    5101
                mstore(0x20, m1)
    5102
                mstore(0x40, m2)
    5103
                mstore(0x60, m3)
    5104
                mstore(0x80, m4)
    5105
                mstore(0xa0, m5)
    5106
                mstore(0xc0, m6)
    5107
            }
    5108
        }
    5109
    5110
        function log(address p0, bytes32 p1, bool p2, bytes32 p3) internal pure {
    5111
            bytes32 m0;
    5112
            bytes32 m1;
    5113
            bytes32 m2;
    5114
            bytes32 m3;
    5115
            bytes32 m4;
    5116
            bytes32 m5;
    5117
            bytes32 m6;
    5118
            bytes32 m7;
    5119
            bytes32 m8;
    5120
            /// @solidity memory-safe-assembly
    5121
            assembly {
    5122
                function writeString(pos, w) {
    5123
                    let length := 0
    5124
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    5125
                    mstore(pos, length)
    5126
                    let shift := sub(256, shl(3, length))
    5127
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    5128
                }
    5129
                m0 := mload(0x00)
    5130
                m1 := mload(0x20)
    5131
                m2 := mload(0x40)
    5132
                m3 := mload(0x60)
    5133
                m4 := mload(0x80)
    5134
                m5 := mload(0xa0)
    5135
                m6 := mload(0xc0)
    5136
                m7 := mload(0xe0)
    5137
                m8 := mload(0x100)
    5138
                // Selector of `log(address,string,bool,string)`.
    5139
                mstore(0x00, 0xbc0b61fe)
    5140
                mstore(0x20, p0)
    5141
                mstore(0x40, 0x80)
    5142
                mstore(0x60, p2)
    5143
                mstore(0x80, 0xc0)
    5144
                writeString(0xa0, p1)
    5145
                writeString(0xe0, p3)
    5146
            }
    5147
            _sendLogPayload(0x1c, 0x104);
    5148
            /// @solidity memory-safe-assembly
    5149
            assembly {
    5150
                mstore(0x00, m0)
    5151
                mstore(0x20, m1)
    5152
                mstore(0x40, m2)
    5153
                mstore(0x60, m3)
    5154
                mstore(0x80, m4)
    5155
                mstore(0xa0, m5)
    5156
                mstore(0xc0, m6)
    5157
                mstore(0xe0, m7)
    5158
                mstore(0x100, m8)
    5159
            }
    5160
        }
    5161
    5162
        function log(address p0, bytes32 p1, uint256 p2, address p3) internal pure {
    5163
            bytes32 m0;
    5164
            bytes32 m1;
    5165
            bytes32 m2;
    5166
            bytes32 m3;
    5167
            bytes32 m4;
    5168
            bytes32 m5;
    5169
            bytes32 m6;
    5170
            /// @solidity memory-safe-assembly
    5171
            assembly {
    5172
                function writeString(pos, w) {
    5173
                    let length := 0
    5174
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    5175
                    mstore(pos, length)
    5176
                    let shift := sub(256, shl(3, length))
    5177
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    5178
                }
    5179
                m0 := mload(0x00)
    5180
                m1 := mload(0x20)
    5181
                m2 := mload(0x40)
    5182
                m3 := mload(0x60)
    5183
                m4 := mload(0x80)
    5184
                m5 := mload(0xa0)
    5185
                m6 := mload(0xc0)
    5186
                // Selector of `log(address,string,uint256,address)`.
    5187
                mstore(0x00, 0x63183678)
    5188
                mstore(0x20, p0)
    5189
                mstore(0x40, 0x80)
    5190
                mstore(0x60, p2)
    5191
                mstore(0x80, p3)
    5192
                writeString(0xa0, p1)
    5193
            }
    5194
            _sendLogPayload(0x1c, 0xc4);
    5195
            /// @solidity memory-safe-assembly
    5196
            assembly {
    5197
                mstore(0x00, m0)
    5198
                mstore(0x20, m1)
    5199
                mstore(0x40, m2)
    5200
                mstore(0x60, m3)
    5201
                mstore(0x80, m4)
    5202
                mstore(0xa0, m5)
    5203
                mstore(0xc0, m6)
    5204
            }
    5205
        }
    5206
    5207
        function log(address p0, bytes32 p1, uint256 p2, bool p3) internal pure {
    5208
            bytes32 m0;
    5209
            bytes32 m1;
    5210
            bytes32 m2;
    5211
            bytes32 m3;
    5212
            bytes32 m4;
    5213
            bytes32 m5;
    5214
            bytes32 m6;
    5215
            /// @solidity memory-safe-assembly
    5216
            assembly {
    5217
                function writeString(pos, w) {
    5218
                    let length := 0
    5219
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    5220
                    mstore(pos, length)
    5221
                    let shift := sub(256, shl(3, length))
    5222
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    5223
                }
    5224
                m0 := mload(0x00)
    5225
                m1 := mload(0x20)
    5226
                m2 := mload(0x40)
    5227
                m3 := mload(0x60)
    5228
                m4 := mload(0x80)
    5229
                m5 := mload(0xa0)
    5230
                m6 := mload(0xc0)
    5231
                // Selector of `log(address,string,uint256,bool)`.
    5232
                mstore(0x00, 0x0ef7e050)
    5233
                mstore(0x20, p0)
    5234
                mstore(0x40, 0x80)
    5235
                mstore(0x60, p2)
    5236
                mstore(0x80, p3)
    5237
                writeString(0xa0, p1)
    5238
            }
    5239
            _sendLogPayload(0x1c, 0xc4);
    5240
            /// @solidity memory-safe-assembly
    5241
            assembly {
    5242
                mstore(0x00, m0)
    5243
                mstore(0x20, m1)
    5244
                mstore(0x40, m2)
    5245
                mstore(0x60, m3)
    5246
                mstore(0x80, m4)
    5247
                mstore(0xa0, m5)
    5248
                mstore(0xc0, m6)
    5249
            }
    5250
        }
    5251
    5252
        function log(address p0, bytes32 p1, uint256 p2, uint256 p3) internal pure {
    5253
            bytes32 m0;
    5254
            bytes32 m1;
    5255
            bytes32 m2;
    5256
            bytes32 m3;
    5257
            bytes32 m4;
    5258
            bytes32 m5;
    5259
            bytes32 m6;
    5260
            /// @solidity memory-safe-assembly
    5261
            assembly {
    5262
                function writeString(pos, w) {
    5263
                    let length := 0
    5264
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    5265
                    mstore(pos, length)
    5266
                    let shift := sub(256, shl(3, length))
    5267
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    5268
                }
    5269
                m0 := mload(0x00)
    5270
                m1 := mload(0x20)
    5271
                m2 := mload(0x40)
    5272
                m3 := mload(0x60)
    5273
                m4 := mload(0x80)
    5274
                m5 := mload(0xa0)
    5275
                m6 := mload(0xc0)
    5276
                // Selector of `log(address,string,uint256,uint256)`.
    5277
                mstore(0x00, 0x1dc8e1b8)
    5278
                mstore(0x20, p0)
    5279
                mstore(0x40, 0x80)
    5280
                mstore(0x60, p2)
    5281
                mstore(0x80, p3)
    5282
                writeString(0xa0, p1)
    5283
            }
    5284
            _sendLogPayload(0x1c, 0xc4);
    5285
            /// @solidity memory-safe-assembly
    5286
            assembly {
    5287
                mstore(0x00, m0)
    5288
                mstore(0x20, m1)
    5289
                mstore(0x40, m2)
    5290
                mstore(0x60, m3)
    5291
                mstore(0x80, m4)
    5292
                mstore(0xa0, m5)
    5293
                mstore(0xc0, m6)
    5294
            }
    5295
        }
    5296
    5297
        function log(address p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure {
    5298
            bytes32 m0;
    5299
            bytes32 m1;
    5300
            bytes32 m2;
    5301
            bytes32 m3;
    5302
            bytes32 m4;
    5303
            bytes32 m5;
    5304
            bytes32 m6;
    5305
            bytes32 m7;
    5306
            bytes32 m8;
    5307
            /// @solidity memory-safe-assembly
    5308
            assembly {
    5309
                function writeString(pos, w) {
    5310
                    let length := 0
    5311
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    5312
                    mstore(pos, length)
    5313
                    let shift := sub(256, shl(3, length))
    5314
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    5315
                }
    5316
                m0 := mload(0x00)
    5317
                m1 := mload(0x20)
    5318
                m2 := mload(0x40)
    5319
                m3 := mload(0x60)
    5320
                m4 := mload(0x80)
    5321
                m5 := mload(0xa0)
    5322
                m6 := mload(0xc0)
    5323
                m7 := mload(0xe0)
    5324
                m8 := mload(0x100)
    5325
                // Selector of `log(address,string,uint256,string)`.
    5326
                mstore(0x00, 0x448830a8)
    5327
                mstore(0x20, p0)
    5328
                mstore(0x40, 0x80)
    5329
                mstore(0x60, p2)
    5330
                mstore(0x80, 0xc0)
    5331
                writeString(0xa0, p1)
    5332
                writeString(0xe0, p3)
    5333
            }
    5334
            _sendLogPayload(0x1c, 0x104);
    5335
            /// @solidity memory-safe-assembly
    5336
            assembly {
    5337
                mstore(0x00, m0)
    5338
                mstore(0x20, m1)
    5339
                mstore(0x40, m2)
    5340
                mstore(0x60, m3)
    5341
                mstore(0x80, m4)
    5342
                mstore(0xa0, m5)
    5343
                mstore(0xc0, m6)
    5344
                mstore(0xe0, m7)
    5345
                mstore(0x100, m8)
    5346
            }
    5347
        }
    5348
    5349
        function log(address p0, bytes32 p1, bytes32 p2, address p3) internal pure {
    5350
            bytes32 m0;
    5351
            bytes32 m1;
    5352
            bytes32 m2;
    5353
            bytes32 m3;
    5354
            bytes32 m4;
    5355
            bytes32 m5;
    5356
            bytes32 m6;
    5357
            bytes32 m7;
    5358
            bytes32 m8;
    5359
            /// @solidity memory-safe-assembly
    5360
            assembly {
    5361
                function writeString(pos, w) {
    5362
                    let length := 0
    5363
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    5364
                    mstore(pos, length)
    5365
                    let shift := sub(256, shl(3, length))
    5366
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    5367
                }
    5368
                m0 := mload(0x00)
    5369
                m1 := mload(0x20)
    5370
                m2 := mload(0x40)
    5371
                m3 := mload(0x60)
    5372
                m4 := mload(0x80)
    5373
                m5 := mload(0xa0)
    5374
                m6 := mload(0xc0)
    5375
                m7 := mload(0xe0)
    5376
                m8 := mload(0x100)
    5377
                // Selector of `log(address,string,string,address)`.
    5378
                mstore(0x00, 0xa04e2f87)
    5379
                mstore(0x20, p0)
    5380
                mstore(0x40, 0x80)
    5381
                mstore(0x60, 0xc0)
    5382
                mstore(0x80, p3)
    5383
                writeString(0xa0, p1)
    5384
                writeString(0xe0, p2)
    5385
            }
    5386
            _sendLogPayload(0x1c, 0x104);
    5387
            /// @solidity memory-safe-assembly
    5388
            assembly {
    5389
                mstore(0x00, m0)
    5390
                mstore(0x20, m1)
    5391
                mstore(0x40, m2)
    5392
                mstore(0x60, m3)
    5393
                mstore(0x80, m4)
    5394
                mstore(0xa0, m5)
    5395
                mstore(0xc0, m6)
    5396
                mstore(0xe0, m7)
    5397
                mstore(0x100, m8)
    5398
            }
    5399
        }
    5400
    5401
        function log(address p0, bytes32 p1, bytes32 p2, bool p3) internal pure {
    5402
            bytes32 m0;
    5403
            bytes32 m1;
    5404
            bytes32 m2;
    5405
            bytes32 m3;
    5406
            bytes32 m4;
    5407
            bytes32 m5;
    5408
            bytes32 m6;
    5409
            bytes32 m7;
    5410
            bytes32 m8;
    5411
            /// @solidity memory-safe-assembly
    5412
            assembly {
    5413
                function writeString(pos, w) {
    5414
                    let length := 0
    5415
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    5416
                    mstore(pos, length)
    5417
                    let shift := sub(256, shl(3, length))
    5418
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    5419
                }
    5420
                m0 := mload(0x00)
    5421
                m1 := mload(0x20)
    5422
                m2 := mload(0x40)
    5423
                m3 := mload(0x60)
    5424
                m4 := mload(0x80)
    5425
                m5 := mload(0xa0)
    5426
                m6 := mload(0xc0)
    5427
                m7 := mload(0xe0)
    5428
                m8 := mload(0x100)
    5429
                // Selector of `log(address,string,string,bool)`.
    5430
                mstore(0x00, 0x35a5071f)
    5431
                mstore(0x20, p0)
    5432
                mstore(0x40, 0x80)
    5433
                mstore(0x60, 0xc0)
    5434
                mstore(0x80, p3)
    5435
                writeString(0xa0, p1)
    5436
                writeString(0xe0, p2)
    5437
            }
    5438
            _sendLogPayload(0x1c, 0x104);
    5439
            /// @solidity memory-safe-assembly
    5440
            assembly {
    5441
                mstore(0x00, m0)
    5442
                mstore(0x20, m1)
    5443
                mstore(0x40, m2)
    5444
                mstore(0x60, m3)
    5445
                mstore(0x80, m4)
    5446
                mstore(0xa0, m5)
    5447
                mstore(0xc0, m6)
    5448
                mstore(0xe0, m7)
    5449
                mstore(0x100, m8)
    5450
            }
    5451
        }
    5452
    5453
        function log(address p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure {
    5454
            bytes32 m0;
    5455
            bytes32 m1;
    5456
            bytes32 m2;
    5457
            bytes32 m3;
    5458
            bytes32 m4;
    5459
            bytes32 m5;
    5460
            bytes32 m6;
    5461
            bytes32 m7;
    5462
            bytes32 m8;
    5463
            /// @solidity memory-safe-assembly
    5464
            assembly {
    5465
                function writeString(pos, w) {
    5466
                    let length := 0
    5467
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    5468
                    mstore(pos, length)
    5469
                    let shift := sub(256, shl(3, length))
    5470
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    5471
                }
    5472
                m0 := mload(0x00)
    5473
                m1 := mload(0x20)
    5474
                m2 := mload(0x40)
    5475
                m3 := mload(0x60)
    5476
                m4 := mload(0x80)
    5477
                m5 := mload(0xa0)
    5478
                m6 := mload(0xc0)
    5479
                m7 := mload(0xe0)
    5480
                m8 := mload(0x100)
    5481
                // Selector of `log(address,string,string,uint256)`.
    5482
                mstore(0x00, 0x159f8927)
    5483
                mstore(0x20, p0)
    5484
                mstore(0x40, 0x80)
    5485
                mstore(0x60, 0xc0)
    5486
                mstore(0x80, p3)
    5487
                writeString(0xa0, p1)
    5488
                writeString(0xe0, p2)
    5489
            }
    5490
            _sendLogPayload(0x1c, 0x104);
    5491
            /// @solidity memory-safe-assembly
    5492
            assembly {
    5493
                mstore(0x00, m0)
    5494
                mstore(0x20, m1)
    5495
                mstore(0x40, m2)
    5496
                mstore(0x60, m3)
    5497
                mstore(0x80, m4)
    5498
                mstore(0xa0, m5)
    5499
                mstore(0xc0, m6)
    5500
                mstore(0xe0, m7)
    5501
                mstore(0x100, m8)
    5502
            }
    5503
        }
    5504
    5505
        function log(address p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure {
    5506
            bytes32 m0;
    5507
            bytes32 m1;
    5508
            bytes32 m2;
    5509
            bytes32 m3;
    5510
            bytes32 m4;
    5511
            bytes32 m5;
    5512
            bytes32 m6;
    5513
            bytes32 m7;
    5514
            bytes32 m8;
    5515
            bytes32 m9;
    5516
            bytes32 m10;
    5517
            /// @solidity memory-safe-assembly
    5518
            assembly {
    5519
                function writeString(pos, w) {
    5520
                    let length := 0
    5521
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    5522
                    mstore(pos, length)
    5523
                    let shift := sub(256, shl(3, length))
    5524
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    5525
                }
    5526
                m0 := mload(0x00)
    5527
                m1 := mload(0x20)
    5528
                m2 := mload(0x40)
    5529
                m3 := mload(0x60)
    5530
                m4 := mload(0x80)
    5531
                m5 := mload(0xa0)
    5532
                m6 := mload(0xc0)
    5533
                m7 := mload(0xe0)
    5534
                m8 := mload(0x100)
    5535
                m9 := mload(0x120)
    5536
                m10 := mload(0x140)
    5537
                // Selector of `log(address,string,string,string)`.
    5538
                mstore(0x00, 0x5d02c50b)
    5539
                mstore(0x20, p0)
    5540
                mstore(0x40, 0x80)
    5541
                mstore(0x60, 0xc0)
    5542
                mstore(0x80, 0x100)
    5543
                writeString(0xa0, p1)
    5544
                writeString(0xe0, p2)
    5545
                writeString(0x120, p3)
    5546
            }
    5547
            _sendLogPayload(0x1c, 0x144);
    5548
            /// @solidity memory-safe-assembly
    5549
            assembly {
    5550
                mstore(0x00, m0)
    5551
                mstore(0x20, m1)
    5552
                mstore(0x40, m2)
    5553
                mstore(0x60, m3)
    5554
                mstore(0x80, m4)
    5555
                mstore(0xa0, m5)
    5556
                mstore(0xc0, m6)
    5557
                mstore(0xe0, m7)
    5558
                mstore(0x100, m8)
    5559
                mstore(0x120, m9)
    5560
                mstore(0x140, m10)
    5561
            }
    5562
        }
    5563
    5564
        function log(bool p0, address p1, address p2, address p3) internal pure {
    5565
            bytes32 m0;
    5566
            bytes32 m1;
    5567
            bytes32 m2;
    5568
            bytes32 m3;
    5569
            bytes32 m4;
    5570
            /// @solidity memory-safe-assembly
    5571
            assembly {
    5572
                m0 := mload(0x00)
    5573
                m1 := mload(0x20)
    5574
                m2 := mload(0x40)
    5575
                m3 := mload(0x60)
    5576
                m4 := mload(0x80)
    5577
                // Selector of `log(bool,address,address,address)`.
    5578
                mstore(0x00, 0x1d14d001)
    5579
                mstore(0x20, p0)
    5580
                mstore(0x40, p1)
    5581
                mstore(0x60, p2)
    5582
                mstore(0x80, p3)
    5583
            }
    5584
            _sendLogPayload(0x1c, 0x84);
    5585
            /// @solidity memory-safe-assembly
    5586
            assembly {
    5587
                mstore(0x00, m0)
    5588
                mstore(0x20, m1)
    5589
                mstore(0x40, m2)
    5590
                mstore(0x60, m3)
    5591
                mstore(0x80, m4)
    5592
            }
    5593
        }
    5594
    5595
        function log(bool p0, address p1, address p2, bool p3) internal pure {
    5596
            bytes32 m0;
    5597
            bytes32 m1;
    5598
            bytes32 m2;
    5599
            bytes32 m3;
    5600
            bytes32 m4;
    5601
            /// @solidity memory-safe-assembly
    5602
            assembly {
    5603
                m0 := mload(0x00)
    5604
                m1 := mload(0x20)
    5605
                m2 := mload(0x40)
    5606
                m3 := mload(0x60)
    5607
                m4 := mload(0x80)
    5608
                // Selector of `log(bool,address,address,bool)`.
    5609
                mstore(0x00, 0x46600be0)
    5610
                mstore(0x20, p0)
    5611
                mstore(0x40, p1)
    5612
                mstore(0x60, p2)
    5613
                mstore(0x80, p3)
    5614
            }
    5615
            _sendLogPayload(0x1c, 0x84);
    5616
            /// @solidity memory-safe-assembly
    5617
            assembly {
    5618
                mstore(0x00, m0)
    5619
                mstore(0x20, m1)
    5620
                mstore(0x40, m2)
    5621
                mstore(0x60, m3)
    5622
                mstore(0x80, m4)
    5623
            }
    5624
        }
    5625
    5626
        function log(bool p0, address p1, address p2, uint256 p3) internal pure {
    5627
            bytes32 m0;
    5628
            bytes32 m1;
    5629
            bytes32 m2;
    5630
            bytes32 m3;
    5631
            bytes32 m4;
    5632
            /// @solidity memory-safe-assembly
    5633
            assembly {
    5634
                m0 := mload(0x00)
    5635
                m1 := mload(0x20)
    5636
                m2 := mload(0x40)
    5637
                m3 := mload(0x60)
    5638
                m4 := mload(0x80)
    5639
                // Selector of `log(bool,address,address,uint256)`.
    5640
                mstore(0x00, 0x0c66d1be)
    5641
                mstore(0x20, p0)
    5642
                mstore(0x40, p1)
    5643
                mstore(0x60, p2)
    5644
                mstore(0x80, p3)
    5645
            }
    5646
            _sendLogPayload(0x1c, 0x84);
    5647
            /// @solidity memory-safe-assembly
    5648
            assembly {
    5649
                mstore(0x00, m0)
    5650
                mstore(0x20, m1)
    5651
                mstore(0x40, m2)
    5652
                mstore(0x60, m3)
    5653
                mstore(0x80, m4)
    5654
            }
    5655
        }
    5656
    5657
        function log(bool p0, address p1, address p2, bytes32 p3) internal pure {
    5658
            bytes32 m0;
    5659
            bytes32 m1;
    5660
            bytes32 m2;
    5661
            bytes32 m3;
    5662
            bytes32 m4;
    5663
            bytes32 m5;
    5664
            bytes32 m6;
    5665
            /// @solidity memory-safe-assembly
    5666
            assembly {
    5667
                function writeString(pos, w) {
    5668
                    let length := 0
    5669
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    5670
                    mstore(pos, length)
    5671
                    let shift := sub(256, shl(3, length))
    5672
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    5673
                }
    5674
                m0 := mload(0x00)
    5675
                m1 := mload(0x20)
    5676
                m2 := mload(0x40)
    5677
                m3 := mload(0x60)
    5678
                m4 := mload(0x80)
    5679
                m5 := mload(0xa0)
    5680
                m6 := mload(0xc0)
    5681
                // Selector of `log(bool,address,address,string)`.
    5682
                mstore(0x00, 0xd812a167)
    5683
                mstore(0x20, p0)
    5684
                mstore(0x40, p1)
    5685
                mstore(0x60, p2)
    5686
                mstore(0x80, 0x80)
    5687
                writeString(0xa0, p3)
    5688
            }
    5689
            _sendLogPayload(0x1c, 0xc4);
    5690
            /// @solidity memory-safe-assembly
    5691
            assembly {
    5692
                mstore(0x00, m0)
    5693
                mstore(0x20, m1)
    5694
                mstore(0x40, m2)
    5695
                mstore(0x60, m3)
    5696
                mstore(0x80, m4)
    5697
                mstore(0xa0, m5)
    5698
                mstore(0xc0, m6)
    5699
            }
    5700
        }
    5701
    5702
        function log(bool p0, address p1, bool p2, address p3) internal pure {
    5703
            bytes32 m0;
    5704
            bytes32 m1;
    5705
            bytes32 m2;
    5706
            bytes32 m3;
    5707
            bytes32 m4;
    5708
            /// @solidity memory-safe-assembly
    5709
            assembly {
    5710
                m0 := mload(0x00)
    5711
                m1 := mload(0x20)
    5712
                m2 := mload(0x40)
    5713
                m3 := mload(0x60)
    5714
                m4 := mload(0x80)
    5715
                // Selector of `log(bool,address,bool,address)`.
    5716
                mstore(0x00, 0x1c41a336)
    5717
                mstore(0x20, p0)
    5718
                mstore(0x40, p1)
    5719
                mstore(0x60, p2)
    5720
                mstore(0x80, p3)
    5721
            }
    5722
            _sendLogPayload(0x1c, 0x84);
    5723
            /// @solidity memory-safe-assembly
    5724
            assembly {
    5725
                mstore(0x00, m0)
    5726
                mstore(0x20, m1)
    5727
                mstore(0x40, m2)
    5728
                mstore(0x60, m3)
    5729
                mstore(0x80, m4)
    5730
            }
    5731
        }
    5732
    5733
        function log(bool p0, address p1, bool p2, bool p3) internal pure {
    5734
            bytes32 m0;
    5735
            bytes32 m1;
    5736
            bytes32 m2;
    5737
            bytes32 m3;
    5738
            bytes32 m4;
    5739
            /// @solidity memory-safe-assembly
    5740
            assembly {
    5741
                m0 := mload(0x00)
    5742
                m1 := mload(0x20)
    5743
                m2 := mload(0x40)
    5744
                m3 := mload(0x60)
    5745
                m4 := mload(0x80)
    5746
                // Selector of `log(bool,address,bool,bool)`.
    5747
                mstore(0x00, 0x6a9c478b)
    5748
                mstore(0x20, p0)
    5749
                mstore(0x40, p1)
    5750
                mstore(0x60, p2)
    5751
                mstore(0x80, p3)
    5752
            }
    5753
            _sendLogPayload(0x1c, 0x84);
    5754
            /// @solidity memory-safe-assembly
    5755
            assembly {
    5756
                mstore(0x00, m0)
    5757
                mstore(0x20, m1)
    5758
                mstore(0x40, m2)
    5759
                mstore(0x60, m3)
    5760
                mstore(0x80, m4)
    5761
            }
    5762
        }
    5763
    5764
        function log(bool p0, address p1, bool p2, uint256 p3) internal pure {
    5765
            bytes32 m0;
    5766
            bytes32 m1;
    5767
            bytes32 m2;
    5768
            bytes32 m3;
    5769
            bytes32 m4;
    5770
            /// @solidity memory-safe-assembly
    5771
            assembly {
    5772
                m0 := mload(0x00)
    5773
                m1 := mload(0x20)
    5774
                m2 := mload(0x40)
    5775
                m3 := mload(0x60)
    5776
                m4 := mload(0x80)
    5777
                // Selector of `log(bool,address,bool,uint256)`.
    5778
                mstore(0x00, 0x07831502)
    5779
                mstore(0x20, p0)
    5780
                mstore(0x40, p1)
    5781
                mstore(0x60, p2)
    5782
                mstore(0x80, p3)
    5783
            }
    5784
            _sendLogPayload(0x1c, 0x84);
    5785
            /// @solidity memory-safe-assembly
    5786
            assembly {
    5787
                mstore(0x00, m0)
    5788
                mstore(0x20, m1)
    5789
                mstore(0x40, m2)
    5790
                mstore(0x60, m3)
    5791
                mstore(0x80, m4)
    5792
            }
    5793
        }
    5794
    5795
        function log(bool p0, address p1, bool p2, bytes32 p3) internal pure {
    5796
            bytes32 m0;
    5797
            bytes32 m1;
    5798
            bytes32 m2;
    5799
            bytes32 m3;
    5800
            bytes32 m4;
    5801
            bytes32 m5;
    5802
            bytes32 m6;
    5803
            /// @solidity memory-safe-assembly
    5804
            assembly {
    5805
                function writeString(pos, w) {
    5806
                    let length := 0
    5807
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    5808
                    mstore(pos, length)
    5809
                    let shift := sub(256, shl(3, length))
    5810
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    5811
                }
    5812
                m0 := mload(0x00)
    5813
                m1 := mload(0x20)
    5814
                m2 := mload(0x40)
    5815
                m3 := mload(0x60)
    5816
                m4 := mload(0x80)
    5817
                m5 := mload(0xa0)
    5818
                m6 := mload(0xc0)
    5819
                // Selector of `log(bool,address,bool,string)`.
    5820
                mstore(0x00, 0x4a66cb34)
    5821
                mstore(0x20, p0)
    5822
                mstore(0x40, p1)
    5823
                mstore(0x60, p2)
    5824
                mstore(0x80, 0x80)
    5825
                writeString(0xa0, p3)
    5826
            }
    5827
            _sendLogPayload(0x1c, 0xc4);
    5828
            /// @solidity memory-safe-assembly
    5829
            assembly {
    5830
                mstore(0x00, m0)
    5831
                mstore(0x20, m1)
    5832
                mstore(0x40, m2)
    5833
                mstore(0x60, m3)
    5834
                mstore(0x80, m4)
    5835
                mstore(0xa0, m5)
    5836
                mstore(0xc0, m6)
    5837
            }
    5838
        }
    5839
    5840
        function log(bool p0, address p1, uint256 p2, address p3) internal pure {
    5841
            bytes32 m0;
    5842
            bytes32 m1;
    5843
            bytes32 m2;
    5844
            bytes32 m3;
    5845
            bytes32 m4;
    5846
            /// @solidity memory-safe-assembly
    5847
            assembly {
    5848
                m0 := mload(0x00)
    5849
                m1 := mload(0x20)
    5850
                m2 := mload(0x40)
    5851
                m3 := mload(0x60)
    5852
                m4 := mload(0x80)
    5853
                // Selector of `log(bool,address,uint256,address)`.
    5854
                mstore(0x00, 0x136b05dd)
    5855
                mstore(0x20, p0)
    5856
                mstore(0x40, p1)
    5857
                mstore(0x60, p2)
    5858
                mstore(0x80, p3)
    5859
            }
    5860
            _sendLogPayload(0x1c, 0x84);
    5861
            /// @solidity memory-safe-assembly
    5862
            assembly {
    5863
                mstore(0x00, m0)
    5864
                mstore(0x20, m1)
    5865
                mstore(0x40, m2)
    5866
                mstore(0x60, m3)
    5867
                mstore(0x80, m4)
    5868
            }
    5869
        }
    5870
    5871
        function log(bool p0, address p1, uint256 p2, bool p3) internal pure {
    5872
            bytes32 m0;
    5873
            bytes32 m1;
    5874
            bytes32 m2;
    5875
            bytes32 m3;
    5876
            bytes32 m4;
    5877
            /// @solidity memory-safe-assembly
    5878
            assembly {
    5879
                m0 := mload(0x00)
    5880
                m1 := mload(0x20)
    5881
                m2 := mload(0x40)
    5882
                m3 := mload(0x60)
    5883
                m4 := mload(0x80)
    5884
                // Selector of `log(bool,address,uint256,bool)`.
    5885
                mstore(0x00, 0xd6019f1c)
    5886
                mstore(0x20, p0)
    5887
                mstore(0x40, p1)
    5888
                mstore(0x60, p2)
    5889
                mstore(0x80, p3)
    5890
            }
    5891
            _sendLogPayload(0x1c, 0x84);
    5892
            /// @solidity memory-safe-assembly
    5893
            assembly {
    5894
                mstore(0x00, m0)
    5895
                mstore(0x20, m1)
    5896
                mstore(0x40, m2)
    5897
                mstore(0x60, m3)
    5898
                mstore(0x80, m4)
    5899
            }
    5900
        }
    5901
    5902
        function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure {
    5903
            bytes32 m0;
    5904
            bytes32 m1;
    5905
            bytes32 m2;
    5906
            bytes32 m3;
    5907
            bytes32 m4;
    5908
            /// @solidity memory-safe-assembly
    5909
            assembly {
    5910
                m0 := mload(0x00)
    5911
                m1 := mload(0x20)
    5912
                m2 := mload(0x40)
    5913
                m3 := mload(0x60)
    5914
                m4 := mload(0x80)
    5915
                // Selector of `log(bool,address,uint256,uint256)`.
    5916
                mstore(0x00, 0x7bf181a1)
    5917
                mstore(0x20, p0)
    5918
                mstore(0x40, p1)
    5919
                mstore(0x60, p2)
    5920
                mstore(0x80, p3)
    5921
            }
    5922
            _sendLogPayload(0x1c, 0x84);
    5923
            /// @solidity memory-safe-assembly
    5924
            assembly {
    5925
                mstore(0x00, m0)
    5926
                mstore(0x20, m1)
    5927
                mstore(0x40, m2)
    5928
                mstore(0x60, m3)
    5929
                mstore(0x80, m4)
    5930
            }
    5931
        }
    5932
    5933
        function log(bool p0, address p1, uint256 p2, bytes32 p3) internal pure {
    5934
            bytes32 m0;
    5935
            bytes32 m1;
    5936
            bytes32 m2;
    5937
            bytes32 m3;
    5938
            bytes32 m4;
    5939
            bytes32 m5;
    5940
            bytes32 m6;
    5941
            /// @solidity memory-safe-assembly
    5942
            assembly {
    5943
                function writeString(pos, w) {
    5944
                    let length := 0
    5945
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    5946
                    mstore(pos, length)
    5947
                    let shift := sub(256, shl(3, length))
    5948
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    5949
                }
    5950
                m0 := mload(0x00)
    5951
                m1 := mload(0x20)
    5952
                m2 := mload(0x40)
    5953
                m3 := mload(0x60)
    5954
                m4 := mload(0x80)
    5955
                m5 := mload(0xa0)
    5956
                m6 := mload(0xc0)
    5957
                // Selector of `log(bool,address,uint256,string)`.
    5958
                mstore(0x00, 0x51f09ff8)
    5959
                mstore(0x20, p0)
    5960
                mstore(0x40, p1)
    5961
                mstore(0x60, p2)
    5962
                mstore(0x80, 0x80)
    5963
                writeString(0xa0, p3)
    5964
            }
    5965
            _sendLogPayload(0x1c, 0xc4);
    5966
            /// @solidity memory-safe-assembly
    5967
            assembly {
    5968
                mstore(0x00, m0)
    5969
                mstore(0x20, m1)
    5970
                mstore(0x40, m2)
    5971
                mstore(0x60, m3)
    5972
                mstore(0x80, m4)
    5973
                mstore(0xa0, m5)
    5974
                mstore(0xc0, m6)
    5975
            }
    5976
        }
    5977
    5978
        function log(bool p0, address p1, bytes32 p2, address p3) internal pure {
    5979
            bytes32 m0;
    5980
            bytes32 m1;
    5981
            bytes32 m2;
    5982
            bytes32 m3;
    5983
            bytes32 m4;
    5984
            bytes32 m5;
    5985
            bytes32 m6;
    5986
            /// @solidity memory-safe-assembly
    5987
            assembly {
    5988
                function writeString(pos, w) {
    5989
                    let length := 0
    5990
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    5991
                    mstore(pos, length)
    5992
                    let shift := sub(256, shl(3, length))
    5993
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    5994
                }
    5995
                m0 := mload(0x00)
    5996
                m1 := mload(0x20)
    5997
                m2 := mload(0x40)
    5998
                m3 := mload(0x60)
    5999
                m4 := mload(0x80)
    6000
                m5 := mload(0xa0)
    6001
                m6 := mload(0xc0)
    6002
                // Selector of `log(bool,address,string,address)`.
    6003
                mstore(0x00, 0x6f7c603e)
    6004
                mstore(0x20, p0)
    6005
                mstore(0x40, p1)
    6006
                mstore(0x60, 0x80)
    6007
                mstore(0x80, p3)
    6008
                writeString(0xa0, p2)
    6009
            }
    6010
            _sendLogPayload(0x1c, 0xc4);
    6011
            /// @solidity memory-safe-assembly
    6012
            assembly {
    6013
                mstore(0x00, m0)
    6014
                mstore(0x20, m1)
    6015
                mstore(0x40, m2)
    6016
                mstore(0x60, m3)
    6017
                mstore(0x80, m4)
    6018
                mstore(0xa0, m5)
    6019
                mstore(0xc0, m6)
    6020
            }
    6021
        }
    6022
    6023
        function log(bool p0, address p1, bytes32 p2, bool p3) internal pure {
    6024
            bytes32 m0;
    6025
            bytes32 m1;
    6026
            bytes32 m2;
    6027
            bytes32 m3;
    6028
            bytes32 m4;
    6029
            bytes32 m5;
    6030
            bytes32 m6;
    6031
            /// @solidity memory-safe-assembly
    6032
            assembly {
    6033
                function writeString(pos, w) {
    6034
                    let length := 0
    6035
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    6036
                    mstore(pos, length)
    6037
                    let shift := sub(256, shl(3, length))
    6038
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    6039
                }
    6040
                m0 := mload(0x00)
    6041
                m1 := mload(0x20)
    6042
                m2 := mload(0x40)
    6043
                m3 := mload(0x60)
    6044
                m4 := mload(0x80)
    6045
                m5 := mload(0xa0)
    6046
                m6 := mload(0xc0)
    6047
                // Selector of `log(bool,address,string,bool)`.
    6048
                mstore(0x00, 0xe2bfd60b)
    6049
                mstore(0x20, p0)
    6050
                mstore(0x40, p1)
    6051
                mstore(0x60, 0x80)
    6052
                mstore(0x80, p3)
    6053
                writeString(0xa0, p2)
    6054
            }
    6055
            _sendLogPayload(0x1c, 0xc4);
    6056
            /// @solidity memory-safe-assembly
    6057
            assembly {
    6058
                mstore(0x00, m0)
    6059
                mstore(0x20, m1)
    6060
                mstore(0x40, m2)
    6061
                mstore(0x60, m3)
    6062
                mstore(0x80, m4)
    6063
                mstore(0xa0, m5)
    6064
                mstore(0xc0, m6)
    6065
            }
    6066
        }
    6067
    6068
        function log(bool p0, address p1, bytes32 p2, uint256 p3) internal pure {
    6069
            bytes32 m0;
    6070
            bytes32 m1;
    6071
            bytes32 m2;
    6072
            bytes32 m3;
    6073
            bytes32 m4;
    6074
            bytes32 m5;
    6075
            bytes32 m6;
    6076
            /// @solidity memory-safe-assembly
    6077
            assembly {
    6078
                function writeString(pos, w) {
    6079
                    let length := 0
    6080
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    6081
                    mstore(pos, length)
    6082
                    let shift := sub(256, shl(3, length))
    6083
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    6084
                }
    6085
                m0 := mload(0x00)
    6086
                m1 := mload(0x20)
    6087
                m2 := mload(0x40)
    6088
                m3 := mload(0x60)
    6089
                m4 := mload(0x80)
    6090
                m5 := mload(0xa0)
    6091
                m6 := mload(0xc0)
    6092
                // Selector of `log(bool,address,string,uint256)`.
    6093
                mstore(0x00, 0xc21f64c7)
    6094
                mstore(0x20, p0)
    6095
                mstore(0x40, p1)
    6096
                mstore(0x60, 0x80)
    6097
                mstore(0x80, p3)
    6098
                writeString(0xa0, p2)
    6099
            }
    6100
            _sendLogPayload(0x1c, 0xc4);
    6101
            /// @solidity memory-safe-assembly
    6102
            assembly {
    6103
                mstore(0x00, m0)
    6104
                mstore(0x20, m1)
    6105
                mstore(0x40, m2)
    6106
                mstore(0x60, m3)
    6107
                mstore(0x80, m4)
    6108
                mstore(0xa0, m5)
    6109
                mstore(0xc0, m6)
    6110
            }
    6111
        }
    6112
    6113
        function log(bool p0, address p1, bytes32 p2, bytes32 p3) internal pure {
    6114
            bytes32 m0;
    6115
            bytes32 m1;
    6116
            bytes32 m2;
    6117
            bytes32 m3;
    6118
            bytes32 m4;
    6119
            bytes32 m5;
    6120
            bytes32 m6;
    6121
            bytes32 m7;
    6122
            bytes32 m8;
    6123
            /// @solidity memory-safe-assembly
    6124
            assembly {
    6125
                function writeString(pos, w) {
    6126
                    let length := 0
    6127
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    6128
                    mstore(pos, length)
    6129
                    let shift := sub(256, shl(3, length))
    6130
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    6131
                }
    6132
                m0 := mload(0x00)
    6133
                m1 := mload(0x20)
    6134
                m2 := mload(0x40)
    6135
                m3 := mload(0x60)
    6136
                m4 := mload(0x80)
    6137
                m5 := mload(0xa0)
    6138
                m6 := mload(0xc0)
    6139
                m7 := mload(0xe0)
    6140
                m8 := mload(0x100)
    6141
                // Selector of `log(bool,address,string,string)`.
    6142
                mstore(0x00, 0xa73c1db6)
    6143
                mstore(0x20, p0)
    6144
                mstore(0x40, p1)
    6145
                mstore(0x60, 0x80)
    6146
                mstore(0x80, 0xc0)
    6147
                writeString(0xa0, p2)
    6148
                writeString(0xe0, p3)
    6149
            }
    6150
            _sendLogPayload(0x1c, 0x104);
    6151
            /// @solidity memory-safe-assembly
    6152
            assembly {
    6153
                mstore(0x00, m0)
    6154
                mstore(0x20, m1)
    6155
                mstore(0x40, m2)
    6156
                mstore(0x60, m3)
    6157
                mstore(0x80, m4)
    6158
                mstore(0xa0, m5)
    6159
                mstore(0xc0, m6)
    6160
                mstore(0xe0, m7)
    6161
                mstore(0x100, m8)
    6162
            }
    6163
        }
    6164
    6165
        function log(bool p0, bool p1, address p2, address p3) internal pure {
    6166
            bytes32 m0;
    6167
            bytes32 m1;
    6168
            bytes32 m2;
    6169
            bytes32 m3;
    6170
            bytes32 m4;
    6171
            /// @solidity memory-safe-assembly
    6172
            assembly {
    6173
                m0 := mload(0x00)
    6174
                m1 := mload(0x20)
    6175
                m2 := mload(0x40)
    6176
                m3 := mload(0x60)
    6177
                m4 := mload(0x80)
    6178
                // Selector of `log(bool,bool,address,address)`.
    6179
                mstore(0x00, 0xf4880ea4)
    6180
                mstore(0x20, p0)
    6181
                mstore(0x40, p1)
    6182
                mstore(0x60, p2)
    6183
                mstore(0x80, p3)
    6184
            }
    6185
            _sendLogPayload(0x1c, 0x84);
    6186
            /// @solidity memory-safe-assembly
    6187
            assembly {
    6188
                mstore(0x00, m0)
    6189
                mstore(0x20, m1)
    6190
                mstore(0x40, m2)
    6191
                mstore(0x60, m3)
    6192
                mstore(0x80, m4)
    6193
            }
    6194
        }
    6195
    6196
        function log(bool p0, bool p1, address p2, bool p3) internal pure {
    6197
            bytes32 m0;
    6198
            bytes32 m1;
    6199
            bytes32 m2;
    6200
            bytes32 m3;
    6201
            bytes32 m4;
    6202
            /// @solidity memory-safe-assembly
    6203
            assembly {
    6204
                m0 := mload(0x00)
    6205
                m1 := mload(0x20)
    6206
                m2 := mload(0x40)
    6207
                m3 := mload(0x60)
    6208
                m4 := mload(0x80)
    6209
                // Selector of `log(bool,bool,address,bool)`.
    6210
                mstore(0x00, 0xc0a302d8)
    6211
                mstore(0x20, p0)
    6212
                mstore(0x40, p1)
    6213
                mstore(0x60, p2)
    6214
                mstore(0x80, p3)
    6215
            }
    6216
            _sendLogPayload(0x1c, 0x84);
    6217
            /// @solidity memory-safe-assembly
    6218
            assembly {
    6219
                mstore(0x00, m0)
    6220
                mstore(0x20, m1)
    6221
                mstore(0x40, m2)
    6222
                mstore(0x60, m3)
    6223
                mstore(0x80, m4)
    6224
            }
    6225
        }
    6226
    6227
        function log(bool p0, bool p1, address p2, uint256 p3) internal pure {
    6228
            bytes32 m0;
    6229
            bytes32 m1;
    6230
            bytes32 m2;
    6231
            bytes32 m3;
    6232
            bytes32 m4;
    6233
            /// @solidity memory-safe-assembly
    6234
            assembly {
    6235
                m0 := mload(0x00)
    6236
                m1 := mload(0x20)
    6237
                m2 := mload(0x40)
    6238
                m3 := mload(0x60)
    6239
                m4 := mload(0x80)
    6240
                // Selector of `log(bool,bool,address,uint256)`.
    6241
                mstore(0x00, 0x4c123d57)
    6242
                mstore(0x20, p0)
    6243
                mstore(0x40, p1)
    6244
                mstore(0x60, p2)
    6245
                mstore(0x80, p3)
    6246
            }
    6247
            _sendLogPayload(0x1c, 0x84);
    6248
            /// @solidity memory-safe-assembly
    6249
            assembly {
    6250
                mstore(0x00, m0)
    6251
                mstore(0x20, m1)
    6252
                mstore(0x40, m2)
    6253
                mstore(0x60, m3)
    6254
                mstore(0x80, m4)
    6255
            }
    6256
        }
    6257
    6258
        function log(bool p0, bool p1, address p2, bytes32 p3) internal pure {
    6259
            bytes32 m0;
    6260
            bytes32 m1;
    6261
            bytes32 m2;
    6262
            bytes32 m3;
    6263
            bytes32 m4;
    6264
            bytes32 m5;
    6265
            bytes32 m6;
    6266
            /// @solidity memory-safe-assembly
    6267
            assembly {
    6268
                function writeString(pos, w) {
    6269
                    let length := 0
    6270
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    6271
                    mstore(pos, length)
    6272
                    let shift := sub(256, shl(3, length))
    6273
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    6274
                }
    6275
                m0 := mload(0x00)
    6276
                m1 := mload(0x20)
    6277
                m2 := mload(0x40)
    6278
                m3 := mload(0x60)
    6279
                m4 := mload(0x80)
    6280
                m5 := mload(0xa0)
    6281
                m6 := mload(0xc0)
    6282
                // Selector of `log(bool,bool,address,string)`.
    6283
                mstore(0x00, 0xa0a47963)
    6284
                mstore(0x20, p0)
    6285
                mstore(0x40, p1)
    6286
                mstore(0x60, p2)
    6287
                mstore(0x80, 0x80)
    6288
                writeString(0xa0, p3)
    6289
            }
    6290
            _sendLogPayload(0x1c, 0xc4);
    6291
            /// @solidity memory-safe-assembly
    6292
            assembly {
    6293
                mstore(0x00, m0)
    6294
                mstore(0x20, m1)
    6295
                mstore(0x40, m2)
    6296
                mstore(0x60, m3)
    6297
                mstore(0x80, m4)
    6298
                mstore(0xa0, m5)
    6299
                mstore(0xc0, m6)
    6300
            }
    6301
        }
    6302
    6303
        function log(bool p0, bool p1, bool p2, address p3) internal pure {
    6304
            bytes32 m0;
    6305
            bytes32 m1;
    6306
            bytes32 m2;
    6307
            bytes32 m3;
    6308
            bytes32 m4;
    6309
            /// @solidity memory-safe-assembly
    6310
            assembly {
    6311
                m0 := mload(0x00)
    6312
                m1 := mload(0x20)
    6313
                m2 := mload(0x40)
    6314
                m3 := mload(0x60)
    6315
                m4 := mload(0x80)
    6316
                // Selector of `log(bool,bool,bool,address)`.
    6317
                mstore(0x00, 0x8c329b1a)
    6318
                mstore(0x20, p0)
    6319
                mstore(0x40, p1)
    6320
                mstore(0x60, p2)
    6321
                mstore(0x80, p3)
    6322
            }
    6323
            _sendLogPayload(0x1c, 0x84);
    6324
            /// @solidity memory-safe-assembly
    6325
            assembly {
    6326
                mstore(0x00, m0)
    6327
                mstore(0x20, m1)
    6328
                mstore(0x40, m2)
    6329
                mstore(0x60, m3)
    6330
                mstore(0x80, m4)
    6331
            }
    6332
        }
    6333
    6334
        function log(bool p0, bool p1, bool p2, bool p3) internal pure {
    6335
            bytes32 m0;
    6336
            bytes32 m1;
    6337
            bytes32 m2;
    6338
            bytes32 m3;
    6339
            bytes32 m4;
    6340
            /// @solidity memory-safe-assembly
    6341
            assembly {
    6342
                m0 := mload(0x00)
    6343
                m1 := mload(0x20)
    6344
                m2 := mload(0x40)
    6345
                m3 := mload(0x60)
    6346
                m4 := mload(0x80)
    6347
                // Selector of `log(bool,bool,bool,bool)`.
    6348
                mstore(0x00, 0x3b2a5ce0)
    6349
                mstore(0x20, p0)
    6350
                mstore(0x40, p1)
    6351
                mstore(0x60, p2)
    6352
                mstore(0x80, p3)
    6353
            }
    6354
            _sendLogPayload(0x1c, 0x84);
    6355
            /// @solidity memory-safe-assembly
    6356
            assembly {
    6357
                mstore(0x00, m0)
    6358
                mstore(0x20, m1)
    6359
                mstore(0x40, m2)
    6360
                mstore(0x60, m3)
    6361
                mstore(0x80, m4)
    6362
            }
    6363
        }
    6364
    6365
        function log(bool p0, bool p1, bool p2, uint256 p3) internal pure {
    6366
            bytes32 m0;
    6367
            bytes32 m1;
    6368
            bytes32 m2;
    6369
            bytes32 m3;
    6370
            bytes32 m4;
    6371
            /// @solidity memory-safe-assembly
    6372
            assembly {
    6373
                m0 := mload(0x00)
    6374
                m1 := mload(0x20)
    6375
                m2 := mload(0x40)
    6376
                m3 := mload(0x60)
    6377
                m4 := mload(0x80)
    6378
                // Selector of `log(bool,bool,bool,uint256)`.
    6379
                mstore(0x00, 0x6d7045c1)
    6380
                mstore(0x20, p0)
    6381
                mstore(0x40, p1)
    6382
                mstore(0x60, p2)
    6383
                mstore(0x80, p3)
    6384
            }
    6385
            _sendLogPayload(0x1c, 0x84);
    6386
            /// @solidity memory-safe-assembly
    6387
            assembly {
    6388
                mstore(0x00, m0)
    6389
                mstore(0x20, m1)
    6390
                mstore(0x40, m2)
    6391
                mstore(0x60, m3)
    6392
                mstore(0x80, m4)
    6393
            }
    6394
        }
    6395
    6396
        function log(bool p0, bool p1, bool p2, bytes32 p3) internal pure {
    6397
            bytes32 m0;
    6398
            bytes32 m1;
    6399
            bytes32 m2;
    6400
            bytes32 m3;
    6401
            bytes32 m4;
    6402
            bytes32 m5;
    6403
            bytes32 m6;
    6404
            /// @solidity memory-safe-assembly
    6405
            assembly {
    6406
                function writeString(pos, w) {
    6407
                    let length := 0
    6408
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    6409
                    mstore(pos, length)
    6410
                    let shift := sub(256, shl(3, length))
    6411
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    6412
                }
    6413
                m0 := mload(0x00)
    6414
                m1 := mload(0x20)
    6415
                m2 := mload(0x40)
    6416
                m3 := mload(0x60)
    6417
                m4 := mload(0x80)
    6418
                m5 := mload(0xa0)
    6419
                m6 := mload(0xc0)
    6420
                // Selector of `log(bool,bool,bool,string)`.
    6421
                mstore(0x00, 0x2ae408d4)
    6422
                mstore(0x20, p0)
    6423
                mstore(0x40, p1)
    6424
                mstore(0x60, p2)
    6425
                mstore(0x80, 0x80)
    6426
                writeString(0xa0, p3)
    6427
            }
    6428
            _sendLogPayload(0x1c, 0xc4);
    6429
            /// @solidity memory-safe-assembly
    6430
            assembly {
    6431
                mstore(0x00, m0)
    6432
                mstore(0x20, m1)
    6433
                mstore(0x40, m2)
    6434
                mstore(0x60, m3)
    6435
                mstore(0x80, m4)
    6436
                mstore(0xa0, m5)
    6437
                mstore(0xc0, m6)
    6438
            }
    6439
        }
    6440
    6441
        function log(bool p0, bool p1, uint256 p2, address p3) internal pure {
    6442
            bytes32 m0;
    6443
            bytes32 m1;
    6444
            bytes32 m2;
    6445
            bytes32 m3;
    6446
            bytes32 m4;
    6447
            /// @solidity memory-safe-assembly
    6448
            assembly {
    6449
                m0 := mload(0x00)
    6450
                m1 := mload(0x20)
    6451
                m2 := mload(0x40)
    6452
                m3 := mload(0x60)
    6453
                m4 := mload(0x80)
    6454
                // Selector of `log(bool,bool,uint256,address)`.
    6455
                mstore(0x00, 0x54a7a9a0)
    6456
                mstore(0x20, p0)
    6457
                mstore(0x40, p1)
    6458
                mstore(0x60, p2)
    6459
                mstore(0x80, p3)
    6460
            }
    6461
            _sendLogPayload(0x1c, 0x84);
    6462
            /// @solidity memory-safe-assembly
    6463
            assembly {
    6464
                mstore(0x00, m0)
    6465
                mstore(0x20, m1)
    6466
                mstore(0x40, m2)
    6467
                mstore(0x60, m3)
    6468
                mstore(0x80, m4)
    6469
            }
    6470
        }
    6471
    6472
        function log(bool p0, bool p1, uint256 p2, bool p3) internal pure {
    6473
            bytes32 m0;
    6474
            bytes32 m1;
    6475
            bytes32 m2;
    6476
            bytes32 m3;
    6477
            bytes32 m4;
    6478
            /// @solidity memory-safe-assembly
    6479
            assembly {
    6480
                m0 := mload(0x00)
    6481
                m1 := mload(0x20)
    6482
                m2 := mload(0x40)
    6483
                m3 := mload(0x60)
    6484
                m4 := mload(0x80)
    6485
                // Selector of `log(bool,bool,uint256,bool)`.
    6486
                mstore(0x00, 0x619e4d0e)
    6487
                mstore(0x20, p0)
    6488
                mstore(0x40, p1)
    6489
                mstore(0x60, p2)
    6490
                mstore(0x80, p3)
    6491
            }
    6492
            _sendLogPayload(0x1c, 0x84);
    6493
            /// @solidity memory-safe-assembly
    6494
            assembly {
    6495
                mstore(0x00, m0)
    6496
                mstore(0x20, m1)
    6497
                mstore(0x40, m2)
    6498
                mstore(0x60, m3)
    6499
                mstore(0x80, m4)
    6500
            }
    6501
        }
    6502
    6503
        function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure {
    6504
            bytes32 m0;
    6505
            bytes32 m1;
    6506
            bytes32 m2;
    6507
            bytes32 m3;
    6508
            bytes32 m4;
    6509
            /// @solidity memory-safe-assembly
    6510
            assembly {
    6511
                m0 := mload(0x00)
    6512
                m1 := mload(0x20)
    6513
                m2 := mload(0x40)
    6514
                m3 := mload(0x60)
    6515
                m4 := mload(0x80)
    6516
                // Selector of `log(bool,bool,uint256,uint256)`.
    6517
                mstore(0x00, 0x0bb00eab)
    6518
                mstore(0x20, p0)
    6519
                mstore(0x40, p1)
    6520
                mstore(0x60, p2)
    6521
                mstore(0x80, p3)
    6522
            }
    6523
            _sendLogPayload(0x1c, 0x84);
    6524
            /// @solidity memory-safe-assembly
    6525
            assembly {
    6526
                mstore(0x00, m0)
    6527
                mstore(0x20, m1)
    6528
                mstore(0x40, m2)
    6529
                mstore(0x60, m3)
    6530
                mstore(0x80, m4)
    6531
            }
    6532
        }
    6533
    6534
        function log(bool p0, bool p1, uint256 p2, bytes32 p3) internal pure {
    6535
            bytes32 m0;
    6536
            bytes32 m1;
    6537
            bytes32 m2;
    6538
            bytes32 m3;
    6539
            bytes32 m4;
    6540
            bytes32 m5;
    6541
            bytes32 m6;
    6542
            /// @solidity memory-safe-assembly
    6543
            assembly {
    6544
                function writeString(pos, w) {
    6545
                    let length := 0
    6546
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    6547
                    mstore(pos, length)
    6548
                    let shift := sub(256, shl(3, length))
    6549
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    6550
                }
    6551
                m0 := mload(0x00)
    6552
                m1 := mload(0x20)
    6553
                m2 := mload(0x40)
    6554
                m3 := mload(0x60)
    6555
                m4 := mload(0x80)
    6556
                m5 := mload(0xa0)
    6557
                m6 := mload(0xc0)
    6558
                // Selector of `log(bool,bool,uint256,string)`.
    6559
                mstore(0x00, 0x7dd4d0e0)
    6560
                mstore(0x20, p0)
    6561
                mstore(0x40, p1)
    6562
                mstore(0x60, p2)
    6563
                mstore(0x80, 0x80)
    6564
                writeString(0xa0, p3)
    6565
            }
    6566
            _sendLogPayload(0x1c, 0xc4);
    6567
            /// @solidity memory-safe-assembly
    6568
            assembly {
    6569
                mstore(0x00, m0)
    6570
                mstore(0x20, m1)
    6571
                mstore(0x40, m2)
    6572
                mstore(0x60, m3)
    6573
                mstore(0x80, m4)
    6574
                mstore(0xa0, m5)
    6575
                mstore(0xc0, m6)
    6576
            }
    6577
        }
    6578
    6579
        function log(bool p0, bool p1, bytes32 p2, address p3) internal pure {
    6580
            bytes32 m0;
    6581
            bytes32 m1;
    6582
            bytes32 m2;
    6583
            bytes32 m3;
    6584
            bytes32 m4;
    6585
            bytes32 m5;
    6586
            bytes32 m6;
    6587
            /// @solidity memory-safe-assembly
    6588
            assembly {
    6589
                function writeString(pos, w) {
    6590
                    let length := 0
    6591
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    6592
                    mstore(pos, length)
    6593
                    let shift := sub(256, shl(3, length))
    6594
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    6595
                }
    6596
                m0 := mload(0x00)
    6597
                m1 := mload(0x20)
    6598
                m2 := mload(0x40)
    6599
                m3 := mload(0x60)
    6600
                m4 := mload(0x80)
    6601
                m5 := mload(0xa0)
    6602
                m6 := mload(0xc0)
    6603
                // Selector of `log(bool,bool,string,address)`.
    6604
                mstore(0x00, 0xf9ad2b89)
    6605
                mstore(0x20, p0)
    6606
                mstore(0x40, p1)
    6607
                mstore(0x60, 0x80)
    6608
                mstore(0x80, p3)
    6609
                writeString(0xa0, p2)
    6610
            }
    6611
            _sendLogPayload(0x1c, 0xc4);
    6612
            /// @solidity memory-safe-assembly
    6613
            assembly {
    6614
                mstore(0x00, m0)
    6615
                mstore(0x20, m1)
    6616
                mstore(0x40, m2)
    6617
                mstore(0x60, m3)
    6618
                mstore(0x80, m4)
    6619
                mstore(0xa0, m5)
    6620
                mstore(0xc0, m6)
    6621
            }
    6622
        }
    6623
    6624
        function log(bool p0, bool p1, bytes32 p2, bool p3) internal pure {
    6625
            bytes32 m0;
    6626
            bytes32 m1;
    6627
            bytes32 m2;
    6628
            bytes32 m3;
    6629
            bytes32 m4;
    6630
            bytes32 m5;
    6631
            bytes32 m6;
    6632
            /// @solidity memory-safe-assembly
    6633
            assembly {
    6634
                function writeString(pos, w) {
    6635
                    let length := 0
    6636
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    6637
                    mstore(pos, length)
    6638
                    let shift := sub(256, shl(3, length))
    6639
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    6640
                }
    6641
                m0 := mload(0x00)
    6642
                m1 := mload(0x20)
    6643
                m2 := mload(0x40)
    6644
                m3 := mload(0x60)
    6645
                m4 := mload(0x80)
    6646
                m5 := mload(0xa0)
    6647
                m6 := mload(0xc0)
    6648
                // Selector of `log(bool,bool,string,bool)`.
    6649
                mstore(0x00, 0xb857163a)
    6650
                mstore(0x20, p0)
    6651
                mstore(0x40, p1)
    6652
                mstore(0x60, 0x80)
    6653
                mstore(0x80, p3)
    6654
                writeString(0xa0, p2)
    6655
            }
    6656
            _sendLogPayload(0x1c, 0xc4);
    6657
            /// @solidity memory-safe-assembly
    6658
            assembly {
    6659
                mstore(0x00, m0)
    6660
                mstore(0x20, m1)
    6661
                mstore(0x40, m2)
    6662
                mstore(0x60, m3)
    6663
                mstore(0x80, m4)
    6664
                mstore(0xa0, m5)
    6665
                mstore(0xc0, m6)
    6666
            }
    6667
        }
    6668
    6669
        function log(bool p0, bool p1, bytes32 p2, uint256 p3) internal pure {
    6670
            bytes32 m0;
    6671
            bytes32 m1;
    6672
            bytes32 m2;
    6673
            bytes32 m3;
    6674
            bytes32 m4;
    6675
            bytes32 m5;
    6676
            bytes32 m6;
    6677
            /// @solidity memory-safe-assembly
    6678
            assembly {
    6679
                function writeString(pos, w) {
    6680
                    let length := 0
    6681
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    6682
                    mstore(pos, length)
    6683
                    let shift := sub(256, shl(3, length))
    6684
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    6685
                }
    6686
                m0 := mload(0x00)
    6687
                m1 := mload(0x20)
    6688
                m2 := mload(0x40)
    6689
                m3 := mload(0x60)
    6690
                m4 := mload(0x80)
    6691
                m5 := mload(0xa0)
    6692
                m6 := mload(0xc0)
    6693
                // Selector of `log(bool,bool,string,uint256)`.
    6694
                mstore(0x00, 0xe3a9ca2f)
    6695
                mstore(0x20, p0)
    6696
                mstore(0x40, p1)
    6697
                mstore(0x60, 0x80)
    6698
                mstore(0x80, p3)
    6699
                writeString(0xa0, p2)
    6700
            }
    6701
            _sendLogPayload(0x1c, 0xc4);
    6702
            /// @solidity memory-safe-assembly
    6703
            assembly {
    6704
                mstore(0x00, m0)
    6705
                mstore(0x20, m1)
    6706
                mstore(0x40, m2)
    6707
                mstore(0x60, m3)
    6708
                mstore(0x80, m4)
    6709
                mstore(0xa0, m5)
    6710
                mstore(0xc0, m6)
    6711
            }
    6712
        }
    6713
    6714
        function log(bool p0, bool p1, bytes32 p2, bytes32 p3) internal pure {
    6715
            bytes32 m0;
    6716
            bytes32 m1;
    6717
            bytes32 m2;
    6718
            bytes32 m3;
    6719
            bytes32 m4;
    6720
            bytes32 m5;
    6721
            bytes32 m6;
    6722
            bytes32 m7;
    6723
            bytes32 m8;
    6724
            /// @solidity memory-safe-assembly
    6725
            assembly {
    6726
                function writeString(pos, w) {
    6727
                    let length := 0
    6728
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    6729
                    mstore(pos, length)
    6730
                    let shift := sub(256, shl(3, length))
    6731
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    6732
                }
    6733
                m0 := mload(0x00)
    6734
                m1 := mload(0x20)
    6735
                m2 := mload(0x40)
    6736
                m3 := mload(0x60)
    6737
                m4 := mload(0x80)
    6738
                m5 := mload(0xa0)
    6739
                m6 := mload(0xc0)
    6740
                m7 := mload(0xe0)
    6741
                m8 := mload(0x100)
    6742
                // Selector of `log(bool,bool,string,string)`.
    6743
                mstore(0x00, 0x6d1e8751)
    6744
                mstore(0x20, p0)
    6745
                mstore(0x40, p1)
    6746
                mstore(0x60, 0x80)
    6747
                mstore(0x80, 0xc0)
    6748
                writeString(0xa0, p2)
    6749
                writeString(0xe0, p3)
    6750
            }
    6751
            _sendLogPayload(0x1c, 0x104);
    6752
            /// @solidity memory-safe-assembly
    6753
            assembly {
    6754
                mstore(0x00, m0)
    6755
                mstore(0x20, m1)
    6756
                mstore(0x40, m2)
    6757
                mstore(0x60, m3)
    6758
                mstore(0x80, m4)
    6759
                mstore(0xa0, m5)
    6760
                mstore(0xc0, m6)
    6761
                mstore(0xe0, m7)
    6762
                mstore(0x100, m8)
    6763
            }
    6764
        }
    6765
    6766
        function log(bool p0, uint256 p1, address p2, address p3) internal pure {
    6767
            bytes32 m0;
    6768
            bytes32 m1;
    6769
            bytes32 m2;
    6770
            bytes32 m3;
    6771
            bytes32 m4;
    6772
            /// @solidity memory-safe-assembly
    6773
            assembly {
    6774
                m0 := mload(0x00)
    6775
                m1 := mload(0x20)
    6776
                m2 := mload(0x40)
    6777
                m3 := mload(0x60)
    6778
                m4 := mload(0x80)
    6779
                // Selector of `log(bool,uint256,address,address)`.
    6780
                mstore(0x00, 0x26f560a8)
    6781
                mstore(0x20, p0)
    6782
                mstore(0x40, p1)
    6783
                mstore(0x60, p2)
    6784
                mstore(0x80, p3)
    6785
            }
    6786
            _sendLogPayload(0x1c, 0x84);
    6787
            /// @solidity memory-safe-assembly
    6788
            assembly {
    6789
                mstore(0x00, m0)
    6790
                mstore(0x20, m1)
    6791
                mstore(0x40, m2)
    6792
                mstore(0x60, m3)
    6793
                mstore(0x80, m4)
    6794
            }
    6795
        }
    6796
    6797
        function log(bool p0, uint256 p1, address p2, bool p3) internal pure {
    6798
            bytes32 m0;
    6799
            bytes32 m1;
    6800
            bytes32 m2;
    6801
            bytes32 m3;
    6802
            bytes32 m4;
    6803
            /// @solidity memory-safe-assembly
    6804
            assembly {
    6805
                m0 := mload(0x00)
    6806
                m1 := mload(0x20)
    6807
                m2 := mload(0x40)
    6808
                m3 := mload(0x60)
    6809
                m4 := mload(0x80)
    6810
                // Selector of `log(bool,uint256,address,bool)`.
    6811
                mstore(0x00, 0xb4c314ff)
    6812
                mstore(0x20, p0)
    6813
                mstore(0x40, p1)
    6814
                mstore(0x60, p2)
    6815
                mstore(0x80, p3)
    6816
            }
    6817
            _sendLogPayload(0x1c, 0x84);
    6818
            /// @solidity memory-safe-assembly
    6819
            assembly {
    6820
                mstore(0x00, m0)
    6821
                mstore(0x20, m1)
    6822
                mstore(0x40, m2)
    6823
                mstore(0x60, m3)
    6824
                mstore(0x80, m4)
    6825
            }
    6826
        }
    6827
    6828
        function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure {
    6829
            bytes32 m0;
    6830
            bytes32 m1;
    6831
            bytes32 m2;
    6832
            bytes32 m3;
    6833
            bytes32 m4;
    6834
            /// @solidity memory-safe-assembly
    6835
            assembly {
    6836
                m0 := mload(0x00)
    6837
                m1 := mload(0x20)
    6838
                m2 := mload(0x40)
    6839
                m3 := mload(0x60)
    6840
                m4 := mload(0x80)
    6841
                // Selector of `log(bool,uint256,address,uint256)`.
    6842
                mstore(0x00, 0x1537dc87)
    6843
                mstore(0x20, p0)
    6844
                mstore(0x40, p1)
    6845
                mstore(0x60, p2)
    6846
                mstore(0x80, p3)
    6847
            }
    6848
            _sendLogPayload(0x1c, 0x84);
    6849
            /// @solidity memory-safe-assembly
    6850
            assembly {
    6851
                mstore(0x00, m0)
    6852
                mstore(0x20, m1)
    6853
                mstore(0x40, m2)
    6854
                mstore(0x60, m3)
    6855
                mstore(0x80, m4)
    6856
            }
    6857
        }
    6858
    6859
        function log(bool p0, uint256 p1, address p2, bytes32 p3) internal pure {
    6860
            bytes32 m0;
    6861
            bytes32 m1;
    6862
            bytes32 m2;
    6863
            bytes32 m3;
    6864
            bytes32 m4;
    6865
            bytes32 m5;
    6866
            bytes32 m6;
    6867
            /// @solidity memory-safe-assembly
    6868
            assembly {
    6869
                function writeString(pos, w) {
    6870
                    let length := 0
    6871
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    6872
                    mstore(pos, length)
    6873
                    let shift := sub(256, shl(3, length))
    6874
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    6875
                }
    6876
                m0 := mload(0x00)
    6877
                m1 := mload(0x20)
    6878
                m2 := mload(0x40)
    6879
                m3 := mload(0x60)
    6880
                m4 := mload(0x80)
    6881
                m5 := mload(0xa0)
    6882
                m6 := mload(0xc0)
    6883
                // Selector of `log(bool,uint256,address,string)`.
    6884
                mstore(0x00, 0x1bb3b09a)
    6885
                mstore(0x20, p0)
    6886
                mstore(0x40, p1)
    6887
                mstore(0x60, p2)
    6888
                mstore(0x80, 0x80)
    6889
                writeString(0xa0, p3)
    6890
            }
    6891
            _sendLogPayload(0x1c, 0xc4);
    6892
            /// @solidity memory-safe-assembly
    6893
            assembly {
    6894
                mstore(0x00, m0)
    6895
                mstore(0x20, m1)
    6896
                mstore(0x40, m2)
    6897
                mstore(0x60, m3)
    6898
                mstore(0x80, m4)
    6899
                mstore(0xa0, m5)
    6900
                mstore(0xc0, m6)
    6901
            }
    6902
        }
    6903
    6904
        function log(bool p0, uint256 p1, bool p2, address p3) internal pure {
    6905
            bytes32 m0;
    6906
            bytes32 m1;
    6907
            bytes32 m2;
    6908
            bytes32 m3;
    6909
            bytes32 m4;
    6910
            /// @solidity memory-safe-assembly
    6911
            assembly {
    6912
                m0 := mload(0x00)
    6913
                m1 := mload(0x20)
    6914
                m2 := mload(0x40)
    6915
                m3 := mload(0x60)
    6916
                m4 := mload(0x80)
    6917
                // Selector of `log(bool,uint256,bool,address)`.
    6918
                mstore(0x00, 0x9acd3616)
    6919
                mstore(0x20, p0)
    6920
                mstore(0x40, p1)
    6921
                mstore(0x60, p2)
    6922
                mstore(0x80, p3)
    6923
            }
    6924
            _sendLogPayload(0x1c, 0x84);
    6925
            /// @solidity memory-safe-assembly
    6926
            assembly {
    6927
                mstore(0x00, m0)
    6928
                mstore(0x20, m1)
    6929
                mstore(0x40, m2)
    6930
                mstore(0x60, m3)
    6931
                mstore(0x80, m4)
    6932
            }
    6933
        }
    6934
    6935
        function log(bool p0, uint256 p1, bool p2, bool p3) internal pure {
    6936
            bytes32 m0;
    6937
            bytes32 m1;
    6938
            bytes32 m2;
    6939
            bytes32 m3;
    6940
            bytes32 m4;
    6941
            /// @solidity memory-safe-assembly
    6942
            assembly {
    6943
                m0 := mload(0x00)
    6944
                m1 := mload(0x20)
    6945
                m2 := mload(0x40)
    6946
                m3 := mload(0x60)
    6947
                m4 := mload(0x80)
    6948
                // Selector of `log(bool,uint256,bool,bool)`.
    6949
                mstore(0x00, 0xceb5f4d7)
    6950
                mstore(0x20, p0)
    6951
                mstore(0x40, p1)
    6952
                mstore(0x60, p2)
    6953
                mstore(0x80, p3)
    6954
            }
    6955
            _sendLogPayload(0x1c, 0x84);
    6956
            /// @solidity memory-safe-assembly
    6957
            assembly {
    6958
                mstore(0x00, m0)
    6959
                mstore(0x20, m1)
    6960
                mstore(0x40, m2)
    6961
                mstore(0x60, m3)
    6962
                mstore(0x80, m4)
    6963
            }
    6964
        }
    6965
    6966
        function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure {
    6967
            bytes32 m0;
    6968
            bytes32 m1;
    6969
            bytes32 m2;
    6970
            bytes32 m3;
    6971
            bytes32 m4;
    6972
            /// @solidity memory-safe-assembly
    6973
            assembly {
    6974
                m0 := mload(0x00)
    6975
                m1 := mload(0x20)
    6976
                m2 := mload(0x40)
    6977
                m3 := mload(0x60)
    6978
                m4 := mload(0x80)
    6979
                // Selector of `log(bool,uint256,bool,uint256)`.
    6980
                mstore(0x00, 0x7f9bbca2)
    6981
                mstore(0x20, p0)
    6982
                mstore(0x40, p1)
    6983
                mstore(0x60, p2)
    6984
                mstore(0x80, p3)
    6985
            }
    6986
            _sendLogPayload(0x1c, 0x84);
    6987
            /// @solidity memory-safe-assembly
    6988
            assembly {
    6989
                mstore(0x00, m0)
    6990
                mstore(0x20, m1)
    6991
                mstore(0x40, m2)
    6992
                mstore(0x60, m3)
    6993
                mstore(0x80, m4)
    6994
            }
    6995
        }
    6996
    6997
        function log(bool p0, uint256 p1, bool p2, bytes32 p3) internal pure {
    6998
            bytes32 m0;
    6999
            bytes32 m1;
    7000
            bytes32 m2;
    7001
            bytes32 m3;
    7002
            bytes32 m4;
    7003
            bytes32 m5;
    7004
            bytes32 m6;
    7005
            /// @solidity memory-safe-assembly
    7006
            assembly {
    7007
                function writeString(pos, w) {
    7008
                    let length := 0
    7009
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    7010
                    mstore(pos, length)
    7011
                    let shift := sub(256, shl(3, length))
    7012
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    7013
                }
    7014
                m0 := mload(0x00)
    7015
                m1 := mload(0x20)
    7016
                m2 := mload(0x40)
    7017
                m3 := mload(0x60)
    7018
                m4 := mload(0x80)
    7019
                m5 := mload(0xa0)
    7020
                m6 := mload(0xc0)
    7021
                // Selector of `log(bool,uint256,bool,string)`.
    7022
                mstore(0x00, 0x9143dbb1)
    7023
                mstore(0x20, p0)
    7024
                mstore(0x40, p1)
    7025
                mstore(0x60, p2)
    7026
                mstore(0x80, 0x80)
    7027
                writeString(0xa0, p3)
    7028
            }
    7029
            _sendLogPayload(0x1c, 0xc4);
    7030
            /// @solidity memory-safe-assembly
    7031
            assembly {
    7032
                mstore(0x00, m0)
    7033
                mstore(0x20, m1)
    7034
                mstore(0x40, m2)
    7035
                mstore(0x60, m3)
    7036
                mstore(0x80, m4)
    7037
                mstore(0xa0, m5)
    7038
                mstore(0xc0, m6)
    7039
            }
    7040
        }
    7041
    7042
        function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure {
    7043
            bytes32 m0;
    7044
            bytes32 m1;
    7045
            bytes32 m2;
    7046
            bytes32 m3;
    7047
            bytes32 m4;
    7048
            /// @solidity memory-safe-assembly
    7049
            assembly {
    7050
                m0 := mload(0x00)
    7051
                m1 := mload(0x20)
    7052
                m2 := mload(0x40)
    7053
                m3 := mload(0x60)
    7054
                m4 := mload(0x80)
    7055
                // Selector of `log(bool,uint256,uint256,address)`.
    7056
                mstore(0x00, 0x00dd87b9)
    7057
                mstore(0x20, p0)
    7058
                mstore(0x40, p1)
    7059
                mstore(0x60, p2)
    7060
                mstore(0x80, p3)
    7061
            }
    7062
            _sendLogPayload(0x1c, 0x84);
    7063
            /// @solidity memory-safe-assembly
    7064
            assembly {
    7065
                mstore(0x00, m0)
    7066
                mstore(0x20, m1)
    7067
                mstore(0x40, m2)
    7068
                mstore(0x60, m3)
    7069
                mstore(0x80, m4)
    7070
            }
    7071
        }
    7072
    7073
        function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure {
    7074
            bytes32 m0;
    7075
            bytes32 m1;
    7076
            bytes32 m2;
    7077
            bytes32 m3;
    7078
            bytes32 m4;
    7079
            /// @solidity memory-safe-assembly
    7080
            assembly {
    7081
                m0 := mload(0x00)
    7082
                m1 := mload(0x20)
    7083
                m2 := mload(0x40)
    7084
                m3 := mload(0x60)
    7085
                m4 := mload(0x80)
    7086
                // Selector of `log(bool,uint256,uint256,bool)`.
    7087
                mstore(0x00, 0xbe984353)
    7088
                mstore(0x20, p0)
    7089
                mstore(0x40, p1)
    7090
                mstore(0x60, p2)
    7091
                mstore(0x80, p3)
    7092
            }
    7093
            _sendLogPayload(0x1c, 0x84);
    7094
            /// @solidity memory-safe-assembly
    7095
            assembly {
    7096
                mstore(0x00, m0)
    7097
                mstore(0x20, m1)
    7098
                mstore(0x40, m2)
    7099
                mstore(0x60, m3)
    7100
                mstore(0x80, m4)
    7101
            }
    7102
        }
    7103
    7104
        function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
    7105
            bytes32 m0;
    7106
            bytes32 m1;
    7107
            bytes32 m2;
    7108
            bytes32 m3;
    7109
            bytes32 m4;
    7110
            /// @solidity memory-safe-assembly
    7111
            assembly {
    7112
                m0 := mload(0x00)
    7113
                m1 := mload(0x20)
    7114
                m2 := mload(0x40)
    7115
                m3 := mload(0x60)
    7116
                m4 := mload(0x80)
    7117
                // Selector of `log(bool,uint256,uint256,uint256)`.
    7118
                mstore(0x00, 0x374bb4b2)
    7119
                mstore(0x20, p0)
    7120
                mstore(0x40, p1)
    7121
                mstore(0x60, p2)
    7122
                mstore(0x80, p3)
    7123
            }
    7124
            _sendLogPayload(0x1c, 0x84);
    7125
            /// @solidity memory-safe-assembly
    7126
            assembly {
    7127
                mstore(0x00, m0)
    7128
                mstore(0x20, m1)
    7129
                mstore(0x40, m2)
    7130
                mstore(0x60, m3)
    7131
                mstore(0x80, m4)
    7132
            }
    7133
        }
    7134
    7135
        function log(bool p0, uint256 p1, uint256 p2, bytes32 p3) internal pure {
    7136
            bytes32 m0;
    7137
            bytes32 m1;
    7138
            bytes32 m2;
    7139
            bytes32 m3;
    7140
            bytes32 m4;
    7141
            bytes32 m5;
    7142
            bytes32 m6;
    7143
            /// @solidity memory-safe-assembly
    7144
            assembly {
    7145
                function writeString(pos, w) {
    7146
                    let length := 0
    7147
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    7148
                    mstore(pos, length)
    7149
                    let shift := sub(256, shl(3, length))
    7150
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    7151
                }
    7152
                m0 := mload(0x00)
    7153
                m1 := mload(0x20)
    7154
                m2 := mload(0x40)
    7155
                m3 := mload(0x60)
    7156
                m4 := mload(0x80)
    7157
                m5 := mload(0xa0)
    7158
                m6 := mload(0xc0)
    7159
                // Selector of `log(bool,uint256,uint256,string)`.
    7160
                mstore(0x00, 0x8e69fb5d)
    7161
                mstore(0x20, p0)
    7162
                mstore(0x40, p1)
    7163
                mstore(0x60, p2)
    7164
                mstore(0x80, 0x80)
    7165
                writeString(0xa0, p3)
    7166
            }
    7167
            _sendLogPayload(0x1c, 0xc4);
    7168
            /// @solidity memory-safe-assembly
    7169
            assembly {
    7170
                mstore(0x00, m0)
    7171
                mstore(0x20, m1)
    7172
                mstore(0x40, m2)
    7173
                mstore(0x60, m3)
    7174
                mstore(0x80, m4)
    7175
                mstore(0xa0, m5)
    7176
                mstore(0xc0, m6)
    7177
            }
    7178
        }
    7179
    7180
        function log(bool p0, uint256 p1, bytes32 p2, address p3) internal pure {
    7181
            bytes32 m0;
    7182
            bytes32 m1;
    7183
            bytes32 m2;
    7184
            bytes32 m3;
    7185
            bytes32 m4;
    7186
            bytes32 m5;
    7187
            bytes32 m6;
    7188
            /// @solidity memory-safe-assembly
    7189
            assembly {
    7190
                function writeString(pos, w) {
    7191
                    let length := 0
    7192
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    7193
                    mstore(pos, length)
    7194
                    let shift := sub(256, shl(3, length))
    7195
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    7196
                }
    7197
                m0 := mload(0x00)
    7198
                m1 := mload(0x20)
    7199
                m2 := mload(0x40)
    7200
                m3 := mload(0x60)
    7201
                m4 := mload(0x80)
    7202
                m5 := mload(0xa0)
    7203
                m6 := mload(0xc0)
    7204
                // Selector of `log(bool,uint256,string,address)`.
    7205
                mstore(0x00, 0xfedd1fff)
    7206
                mstore(0x20, p0)
    7207
                mstore(0x40, p1)
    7208
                mstore(0x60, 0x80)
    7209
                mstore(0x80, p3)
    7210
                writeString(0xa0, p2)
    7211
            }
    7212
            _sendLogPayload(0x1c, 0xc4);
    7213
            /// @solidity memory-safe-assembly
    7214
            assembly {
    7215
                mstore(0x00, m0)
    7216
                mstore(0x20, m1)
    7217
                mstore(0x40, m2)
    7218
                mstore(0x60, m3)
    7219
                mstore(0x80, m4)
    7220
                mstore(0xa0, m5)
    7221
                mstore(0xc0, m6)
    7222
            }
    7223
        }
    7224
    7225
        function log(bool p0, uint256 p1, bytes32 p2, bool p3) internal pure {
    7226
            bytes32 m0;
    7227
            bytes32 m1;
    7228
            bytes32 m2;
    7229
            bytes32 m3;
    7230
            bytes32 m4;
    7231
            bytes32 m5;
    7232
            bytes32 m6;
    7233
            /// @solidity memory-safe-assembly
    7234
            assembly {
    7235
                function writeString(pos, w) {
    7236
                    let length := 0
    7237
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    7238
                    mstore(pos, length)
    7239
                    let shift := sub(256, shl(3, length))
    7240
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    7241
                }
    7242
                m0 := mload(0x00)
    7243
                m1 := mload(0x20)
    7244
                m2 := mload(0x40)
    7245
                m3 := mload(0x60)
    7246
                m4 := mload(0x80)
    7247
                m5 := mload(0xa0)
    7248
                m6 := mload(0xc0)
    7249
                // Selector of `log(bool,uint256,string,bool)`.
    7250
                mstore(0x00, 0xe5e70b2b)
    7251
                mstore(0x20, p0)
    7252
                mstore(0x40, p1)
    7253
                mstore(0x60, 0x80)
    7254
                mstore(0x80, p3)
    7255
                writeString(0xa0, p2)
    7256
            }
    7257
            _sendLogPayload(0x1c, 0xc4);
    7258
            /// @solidity memory-safe-assembly
    7259
            assembly {
    7260
                mstore(0x00, m0)
    7261
                mstore(0x20, m1)
    7262
                mstore(0x40, m2)
    7263
                mstore(0x60, m3)
    7264
                mstore(0x80, m4)
    7265
                mstore(0xa0, m5)
    7266
                mstore(0xc0, m6)
    7267
            }
    7268
        }
    7269
    7270
        function log(bool p0, uint256 p1, bytes32 p2, uint256 p3) internal pure {
    7271
            bytes32 m0;
    7272
            bytes32 m1;
    7273
            bytes32 m2;
    7274
            bytes32 m3;
    7275
            bytes32 m4;
    7276
            bytes32 m5;
    7277
            bytes32 m6;
    7278
            /// @solidity memory-safe-assembly
    7279
            assembly {
    7280
                function writeString(pos, w) {
    7281
                    let length := 0
    7282
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    7283
                    mstore(pos, length)
    7284
                    let shift := sub(256, shl(3, length))
    7285
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    7286
                }
    7287
                m0 := mload(0x00)
    7288
                m1 := mload(0x20)
    7289
                m2 := mload(0x40)
    7290
                m3 := mload(0x60)
    7291
                m4 := mload(0x80)
    7292
                m5 := mload(0xa0)
    7293
                m6 := mload(0xc0)
    7294
                // Selector of `log(bool,uint256,string,uint256)`.
    7295
                mstore(0x00, 0x6a1199e2)
    7296
                mstore(0x20, p0)
    7297
                mstore(0x40, p1)
    7298
                mstore(0x60, 0x80)
    7299
                mstore(0x80, p3)
    7300
                writeString(0xa0, p2)
    7301
            }
    7302
            _sendLogPayload(0x1c, 0xc4);
    7303
            /// @solidity memory-safe-assembly
    7304
            assembly {
    7305
                mstore(0x00, m0)
    7306
                mstore(0x20, m1)
    7307
                mstore(0x40, m2)
    7308
                mstore(0x60, m3)
    7309
                mstore(0x80, m4)
    7310
                mstore(0xa0, m5)
    7311
                mstore(0xc0, m6)
    7312
            }
    7313
        }
    7314
    7315
        function log(bool p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure {
    7316
            bytes32 m0;
    7317
            bytes32 m1;
    7318
            bytes32 m2;
    7319
            bytes32 m3;
    7320
            bytes32 m4;
    7321
            bytes32 m5;
    7322
            bytes32 m6;
    7323
            bytes32 m7;
    7324
            bytes32 m8;
    7325
            /// @solidity memory-safe-assembly
    7326
            assembly {
    7327
                function writeString(pos, w) {
    7328
                    let length := 0
    7329
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    7330
                    mstore(pos, length)
    7331
                    let shift := sub(256, shl(3, length))
    7332
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    7333
                }
    7334
                m0 := mload(0x00)
    7335
                m1 := mload(0x20)
    7336
                m2 := mload(0x40)
    7337
                m3 := mload(0x60)
    7338
                m4 := mload(0x80)
    7339
                m5 := mload(0xa0)
    7340
                m6 := mload(0xc0)
    7341
                m7 := mload(0xe0)
    7342
                m8 := mload(0x100)
    7343
                // Selector of `log(bool,uint256,string,string)`.
    7344
                mstore(0x00, 0xf5bc2249)
    7345
                mstore(0x20, p0)
    7346
                mstore(0x40, p1)
    7347
                mstore(0x60, 0x80)
    7348
                mstore(0x80, 0xc0)
    7349
                writeString(0xa0, p2)
    7350
                writeString(0xe0, p3)
    7351
            }
    7352
            _sendLogPayload(0x1c, 0x104);
    7353
            /// @solidity memory-safe-assembly
    7354
            assembly {
    7355
                mstore(0x00, m0)
    7356
                mstore(0x20, m1)
    7357
                mstore(0x40, m2)
    7358
                mstore(0x60, m3)
    7359
                mstore(0x80, m4)
    7360
                mstore(0xa0, m5)
    7361
                mstore(0xc0, m6)
    7362
                mstore(0xe0, m7)
    7363
                mstore(0x100, m8)
    7364
            }
    7365
        }
    7366
    7367
        function log(bool p0, bytes32 p1, address p2, address p3) internal pure {
    7368
            bytes32 m0;
    7369
            bytes32 m1;
    7370
            bytes32 m2;
    7371
            bytes32 m3;
    7372
            bytes32 m4;
    7373
            bytes32 m5;
    7374
            bytes32 m6;
    7375
            /// @solidity memory-safe-assembly
    7376
            assembly {
    7377
                function writeString(pos, w) {
    7378
                    let length := 0
    7379
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    7380
                    mstore(pos, length)
    7381
                    let shift := sub(256, shl(3, length))
    7382
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    7383
                }
    7384
                m0 := mload(0x00)
    7385
                m1 := mload(0x20)
    7386
                m2 := mload(0x40)
    7387
                m3 := mload(0x60)
    7388
                m4 := mload(0x80)
    7389
                m5 := mload(0xa0)
    7390
                m6 := mload(0xc0)
    7391
                // Selector of `log(bool,string,address,address)`.
    7392
                mstore(0x00, 0x2b2b18dc)
    7393
                mstore(0x20, p0)
    7394
                mstore(0x40, 0x80)
    7395
                mstore(0x60, p2)
    7396
                mstore(0x80, p3)
    7397
                writeString(0xa0, p1)
    7398
            }
    7399
            _sendLogPayload(0x1c, 0xc4);
    7400
            /// @solidity memory-safe-assembly
    7401
            assembly {
    7402
                mstore(0x00, m0)
    7403
                mstore(0x20, m1)
    7404
                mstore(0x40, m2)
    7405
                mstore(0x60, m3)
    7406
                mstore(0x80, m4)
    7407
                mstore(0xa0, m5)
    7408
                mstore(0xc0, m6)
    7409
            }
    7410
        }
    7411
    7412
        function log(bool p0, bytes32 p1, address p2, bool p3) internal pure {
    7413
            bytes32 m0;
    7414
            bytes32 m1;
    7415
            bytes32 m2;
    7416
            bytes32 m3;
    7417
            bytes32 m4;
    7418
            bytes32 m5;
    7419
            bytes32 m6;
    7420
            /// @solidity memory-safe-assembly
    7421
            assembly {
    7422
                function writeString(pos, w) {
    7423
                    let length := 0
    7424
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    7425
                    mstore(pos, length)
    7426
                    let shift := sub(256, shl(3, length))
    7427
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    7428
                }
    7429
                m0 := mload(0x00)
    7430
                m1 := mload(0x20)
    7431
                m2 := mload(0x40)
    7432
                m3 := mload(0x60)
    7433
                m4 := mload(0x80)
    7434
                m5 := mload(0xa0)
    7435
                m6 := mload(0xc0)
    7436
                // Selector of `log(bool,string,address,bool)`.
    7437
                mstore(0x00, 0x6dd434ca)
    7438
                mstore(0x20, p0)
    7439
                mstore(0x40, 0x80)
    7440
                mstore(0x60, p2)
    7441
                mstore(0x80, p3)
    7442
                writeString(0xa0, p1)
    7443
            }
    7444
            _sendLogPayload(0x1c, 0xc4);
    7445
            /// @solidity memory-safe-assembly
    7446
            assembly {
    7447
                mstore(0x00, m0)
    7448
                mstore(0x20, m1)
    7449
                mstore(0x40, m2)
    7450
                mstore(0x60, m3)
    7451
                mstore(0x80, m4)
    7452
                mstore(0xa0, m5)
    7453
                mstore(0xc0, m6)
    7454
            }
    7455
        }
    7456
    7457
        function log(bool p0, bytes32 p1, address p2, uint256 p3) internal pure {
    7458
            bytes32 m0;
    7459
            bytes32 m1;
    7460
            bytes32 m2;
    7461
            bytes32 m3;
    7462
            bytes32 m4;
    7463
            bytes32 m5;
    7464
            bytes32 m6;
    7465
            /// @solidity memory-safe-assembly
    7466
            assembly {
    7467
                function writeString(pos, w) {
    7468
                    let length := 0
    7469
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    7470
                    mstore(pos, length)
    7471
                    let shift := sub(256, shl(3, length))
    7472
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    7473
                }
    7474
                m0 := mload(0x00)
    7475
                m1 := mload(0x20)
    7476
                m2 := mload(0x40)
    7477
                m3 := mload(0x60)
    7478
                m4 := mload(0x80)
    7479
                m5 := mload(0xa0)
    7480
                m6 := mload(0xc0)
    7481
                // Selector of `log(bool,string,address,uint256)`.
    7482
                mstore(0x00, 0xa5cada94)
    7483
                mstore(0x20, p0)
    7484
                mstore(0x40, 0x80)
    7485
                mstore(0x60, p2)
    7486
                mstore(0x80, p3)
    7487
                writeString(0xa0, p1)
    7488
            }
    7489
            _sendLogPayload(0x1c, 0xc4);
    7490
            /// @solidity memory-safe-assembly
    7491
            assembly {
    7492
                mstore(0x00, m0)
    7493
                mstore(0x20, m1)
    7494
                mstore(0x40, m2)
    7495
                mstore(0x60, m3)
    7496
                mstore(0x80, m4)
    7497
                mstore(0xa0, m5)
    7498
                mstore(0xc0, m6)
    7499
            }
    7500
        }
    7501
    7502
        function log(bool p0, bytes32 p1, address p2, bytes32 p3) internal pure {
    7503
            bytes32 m0;
    7504
            bytes32 m1;
    7505
            bytes32 m2;
    7506
            bytes32 m3;
    7507
            bytes32 m4;
    7508
            bytes32 m5;
    7509
            bytes32 m6;
    7510
            bytes32 m7;
    7511
            bytes32 m8;
    7512
            /// @solidity memory-safe-assembly
    7513
            assembly {
    7514
                function writeString(pos, w) {
    7515
                    let length := 0
    7516
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    7517
                    mstore(pos, length)
    7518
                    let shift := sub(256, shl(3, length))
    7519
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    7520
                }
    7521
                m0 := mload(0x00)
    7522
                m1 := mload(0x20)
    7523
                m2 := mload(0x40)
    7524
                m3 := mload(0x60)
    7525
                m4 := mload(0x80)
    7526
                m5 := mload(0xa0)
    7527
                m6 := mload(0xc0)
    7528
                m7 := mload(0xe0)
    7529
                m8 := mload(0x100)
    7530
                // Selector of `log(bool,string,address,string)`.
    7531
                mstore(0x00, 0x12d6c788)
    7532
                mstore(0x20, p0)
    7533
                mstore(0x40, 0x80)
    7534
                mstore(0x60, p2)
    7535
                mstore(0x80, 0xc0)
    7536
                writeString(0xa0, p1)
    7537
                writeString(0xe0, p3)
    7538
            }
    7539
            _sendLogPayload(0x1c, 0x104);
    7540
            /// @solidity memory-safe-assembly
    7541
            assembly {
    7542
                mstore(0x00, m0)
    7543
                mstore(0x20, m1)
    7544
                mstore(0x40, m2)
    7545
                mstore(0x60, m3)
    7546
                mstore(0x80, m4)
    7547
                mstore(0xa0, m5)
    7548
                mstore(0xc0, m6)
    7549
                mstore(0xe0, m7)
    7550
                mstore(0x100, m8)
    7551
            }
    7552
        }
    7553
    7554
        function log(bool p0, bytes32 p1, bool p2, address p3) internal pure {
    7555
            bytes32 m0;
    7556
            bytes32 m1;
    7557
            bytes32 m2;
    7558
            bytes32 m3;
    7559
            bytes32 m4;
    7560
            bytes32 m5;
    7561
            bytes32 m6;
    7562
            /// @solidity memory-safe-assembly
    7563
            assembly {
    7564
                function writeString(pos, w) {
    7565
                    let length := 0
    7566
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    7567
                    mstore(pos, length)
    7568
                    let shift := sub(256, shl(3, length))
    7569
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    7570
                }
    7571
                m0 := mload(0x00)
    7572
                m1 := mload(0x20)
    7573
                m2 := mload(0x40)
    7574
                m3 := mload(0x60)
    7575
                m4 := mload(0x80)
    7576
                m5 := mload(0xa0)
    7577
                m6 := mload(0xc0)
    7578
                // Selector of `log(bool,string,bool,address)`.
    7579
                mstore(0x00, 0x538e06ab)
    7580
                mstore(0x20, p0)
    7581
                mstore(0x40, 0x80)
    7582
                mstore(0x60, p2)
    7583
                mstore(0x80, p3)
    7584
                writeString(0xa0, p1)
    7585
            }
    7586
            _sendLogPayload(0x1c, 0xc4);
    7587
            /// @solidity memory-safe-assembly
    7588
            assembly {
    7589
                mstore(0x00, m0)
    7590
                mstore(0x20, m1)
    7591
                mstore(0x40, m2)
    7592
                mstore(0x60, m3)
    7593
                mstore(0x80, m4)
    7594
                mstore(0xa0, m5)
    7595
                mstore(0xc0, m6)
    7596
            }
    7597
        }
    7598
    7599
        function log(bool p0, bytes32 p1, bool p2, bool p3) internal pure {
    7600
            bytes32 m0;
    7601
            bytes32 m1;
    7602
            bytes32 m2;
    7603
            bytes32 m3;
    7604
            bytes32 m4;
    7605
            bytes32 m5;
    7606
            bytes32 m6;
    7607
            /// @solidity memory-safe-assembly
    7608
            assembly {
    7609
                function writeString(pos, w) {
    7610
                    let length := 0
    7611
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    7612
                    mstore(pos, length)
    7613
                    let shift := sub(256, shl(3, length))
    7614
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    7615
                }
    7616
                m0 := mload(0x00)
    7617
                m1 := mload(0x20)
    7618
                m2 := mload(0x40)
    7619
                m3 := mload(0x60)
    7620
                m4 := mload(0x80)
    7621
                m5 := mload(0xa0)
    7622
                m6 := mload(0xc0)
    7623
                // Selector of `log(bool,string,bool,bool)`.
    7624
                mstore(0x00, 0xdc5e935b)
    7625
                mstore(0x20, p0)
    7626
                mstore(0x40, 0x80)
    7627
                mstore(0x60, p2)
    7628
                mstore(0x80, p3)
    7629
                writeString(0xa0, p1)
    7630
            }
    7631
            _sendLogPayload(0x1c, 0xc4);
    7632
            /// @solidity memory-safe-assembly
    7633
            assembly {
    7634
                mstore(0x00, m0)
    7635
                mstore(0x20, m1)
    7636
                mstore(0x40, m2)
    7637
                mstore(0x60, m3)
    7638
                mstore(0x80, m4)
    7639
                mstore(0xa0, m5)
    7640
                mstore(0xc0, m6)
    7641
            }
    7642
        }
    7643
    7644
        function log(bool p0, bytes32 p1, bool p2, uint256 p3) internal pure {
    7645
            bytes32 m0;
    7646
            bytes32 m1;
    7647
            bytes32 m2;
    7648
            bytes32 m3;
    7649
            bytes32 m4;
    7650
            bytes32 m5;
    7651
            bytes32 m6;
    7652
            /// @solidity memory-safe-assembly
    7653
            assembly {
    7654
                function writeString(pos, w) {
    7655
                    let length := 0
    7656
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    7657
                    mstore(pos, length)
    7658
                    let shift := sub(256, shl(3, length))
    7659
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    7660
                }
    7661
                m0 := mload(0x00)
    7662
                m1 := mload(0x20)
    7663
                m2 := mload(0x40)
    7664
                m3 := mload(0x60)
    7665
                m4 := mload(0x80)
    7666
                m5 := mload(0xa0)
    7667
                m6 := mload(0xc0)
    7668
                // Selector of `log(bool,string,bool,uint256)`.
    7669
                mstore(0x00, 0x1606a393)
    7670
                mstore(0x20, p0)
    7671
                mstore(0x40, 0x80)
    7672
                mstore(0x60, p2)
    7673
                mstore(0x80, p3)
    7674
                writeString(0xa0, p1)
    7675
            }
    7676
            _sendLogPayload(0x1c, 0xc4);
    7677
            /// @solidity memory-safe-assembly
    7678
            assembly {
    7679
                mstore(0x00, m0)
    7680
                mstore(0x20, m1)
    7681
                mstore(0x40, m2)
    7682
                mstore(0x60, m3)
    7683
                mstore(0x80, m4)
    7684
                mstore(0xa0, m5)
    7685
                mstore(0xc0, m6)
    7686
            }
    7687
        }
    7688
    7689
        function log(bool p0, bytes32 p1, bool p2, bytes32 p3) internal pure {
    7690
            bytes32 m0;
    7691
            bytes32 m1;
    7692
            bytes32 m2;
    7693
            bytes32 m3;
    7694
            bytes32 m4;
    7695
            bytes32 m5;
    7696
            bytes32 m6;
    7697
            bytes32 m7;
    7698
            bytes32 m8;
    7699
            /// @solidity memory-safe-assembly
    7700
            assembly {
    7701
                function writeString(pos, w) {
    7702
                    let length := 0
    7703
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    7704
                    mstore(pos, length)
    7705
                    let shift := sub(256, shl(3, length))
    7706
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    7707
                }
    7708
                m0 := mload(0x00)
    7709
                m1 := mload(0x20)
    7710
                m2 := mload(0x40)
    7711
                m3 := mload(0x60)
    7712
                m4 := mload(0x80)
    7713
                m5 := mload(0xa0)
    7714
                m6 := mload(0xc0)
    7715
                m7 := mload(0xe0)
    7716
                m8 := mload(0x100)
    7717
                // Selector of `log(bool,string,bool,string)`.
    7718
                mstore(0x00, 0x483d0416)
    7719
                mstore(0x20, p0)
    7720
                mstore(0x40, 0x80)
    7721
                mstore(0x60, p2)
    7722
                mstore(0x80, 0xc0)
    7723
                writeString(0xa0, p1)
    7724
                writeString(0xe0, p3)
    7725
            }
    7726
            _sendLogPayload(0x1c, 0x104);
    7727
            /// @solidity memory-safe-assembly
    7728
            assembly {
    7729
                mstore(0x00, m0)
    7730
                mstore(0x20, m1)
    7731
                mstore(0x40, m2)
    7732
                mstore(0x60, m3)
    7733
                mstore(0x80, m4)
    7734
                mstore(0xa0, m5)
    7735
                mstore(0xc0, m6)
    7736
                mstore(0xe0, m7)
    7737
                mstore(0x100, m8)
    7738
            }
    7739
        }
    7740
    7741
        function log(bool p0, bytes32 p1, uint256 p2, address p3) internal pure {
    7742
            bytes32 m0;
    7743
            bytes32 m1;
    7744
            bytes32 m2;
    7745
            bytes32 m3;
    7746
            bytes32 m4;
    7747
            bytes32 m5;
    7748
            bytes32 m6;
    7749
            /// @solidity memory-safe-assembly
    7750
            assembly {
    7751
                function writeString(pos, w) {
    7752
                    let length := 0
    7753
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    7754
                    mstore(pos, length)
    7755
                    let shift := sub(256, shl(3, length))
    7756
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    7757
                }
    7758
                m0 := mload(0x00)
    7759
                m1 := mload(0x20)
    7760
                m2 := mload(0x40)
    7761
                m3 := mload(0x60)
    7762
                m4 := mload(0x80)
    7763
                m5 := mload(0xa0)
    7764
                m6 := mload(0xc0)
    7765
                // Selector of `log(bool,string,uint256,address)`.
    7766
                mstore(0x00, 0x1596a1ce)
    7767
                mstore(0x20, p0)
    7768
                mstore(0x40, 0x80)
    7769
                mstore(0x60, p2)
    7770
                mstore(0x80, p3)
    7771
                writeString(0xa0, p1)
    7772
            }
    7773
            _sendLogPayload(0x1c, 0xc4);
    7774
            /// @solidity memory-safe-assembly
    7775
            assembly {
    7776
                mstore(0x00, m0)
    7777
                mstore(0x20, m1)
    7778
                mstore(0x40, m2)
    7779
                mstore(0x60, m3)
    7780
                mstore(0x80, m4)
    7781
                mstore(0xa0, m5)
    7782
                mstore(0xc0, m6)
    7783
            }
    7784
        }
    7785
    7786
        function log(bool p0, bytes32 p1, uint256 p2, bool p3) internal pure {
    7787
            bytes32 m0;
    7788
            bytes32 m1;
    7789
            bytes32 m2;
    7790
            bytes32 m3;
    7791
            bytes32 m4;
    7792
            bytes32 m5;
    7793
            bytes32 m6;
    7794
            /// @solidity memory-safe-assembly
    7795
            assembly {
    7796
                function writeString(pos, w) {
    7797
                    let length := 0
    7798
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    7799
                    mstore(pos, length)
    7800
                    let shift := sub(256, shl(3, length))
    7801
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    7802
                }
    7803
                m0 := mload(0x00)
    7804
                m1 := mload(0x20)
    7805
                m2 := mload(0x40)
    7806
                m3 := mload(0x60)
    7807
                m4 := mload(0x80)
    7808
                m5 := mload(0xa0)
    7809
                m6 := mload(0xc0)
    7810
                // Selector of `log(bool,string,uint256,bool)`.
    7811
                mstore(0x00, 0x6b0e5d53)
    7812
                mstore(0x20, p0)
    7813
                mstore(0x40, 0x80)
    7814
                mstore(0x60, p2)
    7815
                mstore(0x80, p3)
    7816
                writeString(0xa0, p1)
    7817
            }
    7818
            _sendLogPayload(0x1c, 0xc4);
    7819
            /// @solidity memory-safe-assembly
    7820
            assembly {
    7821
                mstore(0x00, m0)
    7822
                mstore(0x20, m1)
    7823
                mstore(0x40, m2)
    7824
                mstore(0x60, m3)
    7825
                mstore(0x80, m4)
    7826
                mstore(0xa0, m5)
    7827
                mstore(0xc0, m6)
    7828
            }
    7829
        }
    7830
    7831
        function log(bool p0, bytes32 p1, uint256 p2, uint256 p3) internal pure {
    7832
            bytes32 m0;
    7833
            bytes32 m1;
    7834
            bytes32 m2;
    7835
            bytes32 m3;
    7836
            bytes32 m4;
    7837
            bytes32 m5;
    7838
            bytes32 m6;
    7839
            /// @solidity memory-safe-assembly
    7840
            assembly {
    7841
                function writeString(pos, w) {
    7842
                    let length := 0
    7843
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    7844
                    mstore(pos, length)
    7845
                    let shift := sub(256, shl(3, length))
    7846
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    7847
                }
    7848
                m0 := mload(0x00)
    7849
                m1 := mload(0x20)
    7850
                m2 := mload(0x40)
    7851
                m3 := mload(0x60)
    7852
                m4 := mload(0x80)
    7853
                m5 := mload(0xa0)
    7854
                m6 := mload(0xc0)
    7855
                // Selector of `log(bool,string,uint256,uint256)`.
    7856
                mstore(0x00, 0x28863fcb)
    7857
                mstore(0x20, p0)
    7858
                mstore(0x40, 0x80)
    7859
                mstore(0x60, p2)
    7860
                mstore(0x80, p3)
    7861
                writeString(0xa0, p1)
    7862
            }
    7863
            _sendLogPayload(0x1c, 0xc4);
    7864
            /// @solidity memory-safe-assembly
    7865
            assembly {
    7866
                mstore(0x00, m0)
    7867
                mstore(0x20, m1)
    7868
                mstore(0x40, m2)
    7869
                mstore(0x60, m3)
    7870
                mstore(0x80, m4)
    7871
                mstore(0xa0, m5)
    7872
                mstore(0xc0, m6)
    7873
            }
    7874
        }
    7875
    7876
        function log(bool p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure {
    7877
            bytes32 m0;
    7878
            bytes32 m1;
    7879
            bytes32 m2;
    7880
            bytes32 m3;
    7881
            bytes32 m4;
    7882
            bytes32 m5;
    7883
            bytes32 m6;
    7884
            bytes32 m7;
    7885
            bytes32 m8;
    7886
            /// @solidity memory-safe-assembly
    7887
            assembly {
    7888
                function writeString(pos, w) {
    7889
                    let length := 0
    7890
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    7891
                    mstore(pos, length)
    7892
                    let shift := sub(256, shl(3, length))
    7893
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    7894
                }
    7895
                m0 := mload(0x00)
    7896
                m1 := mload(0x20)
    7897
                m2 := mload(0x40)
    7898
                m3 := mload(0x60)
    7899
                m4 := mload(0x80)
    7900
                m5 := mload(0xa0)
    7901
                m6 := mload(0xc0)
    7902
                m7 := mload(0xe0)
    7903
                m8 := mload(0x100)
    7904
                // Selector of `log(bool,string,uint256,string)`.
    7905
                mstore(0x00, 0x1ad96de6)
    7906
                mstore(0x20, p0)
    7907
                mstore(0x40, 0x80)
    7908
                mstore(0x60, p2)
    7909
                mstore(0x80, 0xc0)
    7910
                writeString(0xa0, p1)
    7911
                writeString(0xe0, p3)
    7912
            }
    7913
            _sendLogPayload(0x1c, 0x104);
    7914
            /// @solidity memory-safe-assembly
    7915
            assembly {
    7916
                mstore(0x00, m0)
    7917
                mstore(0x20, m1)
    7918
                mstore(0x40, m2)
    7919
                mstore(0x60, m3)
    7920
                mstore(0x80, m4)
    7921
                mstore(0xa0, m5)
    7922
                mstore(0xc0, m6)
    7923
                mstore(0xe0, m7)
    7924
                mstore(0x100, m8)
    7925
            }
    7926
        }
    7927
    7928
        function log(bool p0, bytes32 p1, bytes32 p2, address p3) internal pure {
    7929
            bytes32 m0;
    7930
            bytes32 m1;
    7931
            bytes32 m2;
    7932
            bytes32 m3;
    7933
            bytes32 m4;
    7934
            bytes32 m5;
    7935
            bytes32 m6;
    7936
            bytes32 m7;
    7937
            bytes32 m8;
    7938
            /// @solidity memory-safe-assembly
    7939
            assembly {
    7940
                function writeString(pos, w) {
    7941
                    let length := 0
    7942
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    7943
                    mstore(pos, length)
    7944
                    let shift := sub(256, shl(3, length))
    7945
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    7946
                }
    7947
                m0 := mload(0x00)
    7948
                m1 := mload(0x20)
    7949
                m2 := mload(0x40)
    7950
                m3 := mload(0x60)
    7951
                m4 := mload(0x80)
    7952
                m5 := mload(0xa0)
    7953
                m6 := mload(0xc0)
    7954
                m7 := mload(0xe0)
    7955
                m8 := mload(0x100)
    7956
                // Selector of `log(bool,string,string,address)`.
    7957
                mstore(0x00, 0x97d394d8)
    7958
                mstore(0x20, p0)
    7959
                mstore(0x40, 0x80)
    7960
                mstore(0x60, 0xc0)
    7961
                mstore(0x80, p3)
    7962
                writeString(0xa0, p1)
    7963
                writeString(0xe0, p2)
    7964
            }
    7965
            _sendLogPayload(0x1c, 0x104);
    7966
            /// @solidity memory-safe-assembly
    7967
            assembly {
    7968
                mstore(0x00, m0)
    7969
                mstore(0x20, m1)
    7970
                mstore(0x40, m2)
    7971
                mstore(0x60, m3)
    7972
                mstore(0x80, m4)
    7973
                mstore(0xa0, m5)
    7974
                mstore(0xc0, m6)
    7975
                mstore(0xe0, m7)
    7976
                mstore(0x100, m8)
    7977
            }
    7978
        }
    7979
    7980
        function log(bool p0, bytes32 p1, bytes32 p2, bool p3) internal pure {
    7981
            bytes32 m0;
    7982
            bytes32 m1;
    7983
            bytes32 m2;
    7984
            bytes32 m3;
    7985
            bytes32 m4;
    7986
            bytes32 m5;
    7987
            bytes32 m6;
    7988
            bytes32 m7;
    7989
            bytes32 m8;
    7990
            /// @solidity memory-safe-assembly
    7991
            assembly {
    7992
                function writeString(pos, w) {
    7993
                    let length := 0
    7994
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    7995
                    mstore(pos, length)
    7996
                    let shift := sub(256, shl(3, length))
    7997
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    7998
                }
    7999
                m0 := mload(0x00)
    8000
                m1 := mload(0x20)
    8001
                m2 := mload(0x40)
    8002
                m3 := mload(0x60)
    8003
                m4 := mload(0x80)
    8004
                m5 := mload(0xa0)
    8005
                m6 := mload(0xc0)
    8006
                m7 := mload(0xe0)
    8007
                m8 := mload(0x100)
    8008
                // Selector of `log(bool,string,string,bool)`.
    8009
                mstore(0x00, 0x1e4b87e5)
    8010
                mstore(0x20, p0)
    8011
                mstore(0x40, 0x80)
    8012
                mstore(0x60, 0xc0)
    8013
                mstore(0x80, p3)
    8014
                writeString(0xa0, p1)
    8015
                writeString(0xe0, p2)
    8016
            }
    8017
            _sendLogPayload(0x1c, 0x104);
    8018
            /// @solidity memory-safe-assembly
    8019
            assembly {
    8020
                mstore(0x00, m0)
    8021
                mstore(0x20, m1)
    8022
                mstore(0x40, m2)
    8023
                mstore(0x60, m3)
    8024
                mstore(0x80, m4)
    8025
                mstore(0xa0, m5)
    8026
                mstore(0xc0, m6)
    8027
                mstore(0xe0, m7)
    8028
                mstore(0x100, m8)
    8029
            }
    8030
        }
    8031
    8032
        function log(bool p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure {
    8033
            bytes32 m0;
    8034
            bytes32 m1;
    8035
            bytes32 m2;
    8036
            bytes32 m3;
    8037
            bytes32 m4;
    8038
            bytes32 m5;
    8039
            bytes32 m6;
    8040
            bytes32 m7;
    8041
            bytes32 m8;
    8042
            /// @solidity memory-safe-assembly
    8043
            assembly {
    8044
                function writeString(pos, w) {
    8045
                    let length := 0
    8046
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    8047
                    mstore(pos, length)
    8048
                    let shift := sub(256, shl(3, length))
    8049
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    8050
                }
    8051
                m0 := mload(0x00)
    8052
                m1 := mload(0x20)
    8053
                m2 := mload(0x40)
    8054
                m3 := mload(0x60)
    8055
                m4 := mload(0x80)
    8056
                m5 := mload(0xa0)
    8057
                m6 := mload(0xc0)
    8058
                m7 := mload(0xe0)
    8059
                m8 := mload(0x100)
    8060
                // Selector of `log(bool,string,string,uint256)`.
    8061
                mstore(0x00, 0x7be0c3eb)
    8062
                mstore(0x20, p0)
    8063
                mstore(0x40, 0x80)
    8064
                mstore(0x60, 0xc0)
    8065
                mstore(0x80, p3)
    8066
                writeString(0xa0, p1)
    8067
                writeString(0xe0, p2)
    8068
            }
    8069
            _sendLogPayload(0x1c, 0x104);
    8070
            /// @solidity memory-safe-assembly
    8071
            assembly {
    8072
                mstore(0x00, m0)
    8073
                mstore(0x20, m1)
    8074
                mstore(0x40, m2)
    8075
                mstore(0x60, m3)
    8076
                mstore(0x80, m4)
    8077
                mstore(0xa0, m5)
    8078
                mstore(0xc0, m6)
    8079
                mstore(0xe0, m7)
    8080
                mstore(0x100, m8)
    8081
            }
    8082
        }
    8083
    8084
        function log(bool p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure {
    8085
            bytes32 m0;
    8086
            bytes32 m1;
    8087
            bytes32 m2;
    8088
            bytes32 m3;
    8089
            bytes32 m4;
    8090
            bytes32 m5;
    8091
            bytes32 m6;
    8092
            bytes32 m7;
    8093
            bytes32 m8;
    8094
            bytes32 m9;
    8095
            bytes32 m10;
    8096
            /// @solidity memory-safe-assembly
    8097
            assembly {
    8098
                function writeString(pos, w) {
    8099
                    let length := 0
    8100
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    8101
                    mstore(pos, length)
    8102
                    let shift := sub(256, shl(3, length))
    8103
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    8104
                }
    8105
                m0 := mload(0x00)
    8106
                m1 := mload(0x20)
    8107
                m2 := mload(0x40)
    8108
                m3 := mload(0x60)
    8109
                m4 := mload(0x80)
    8110
                m5 := mload(0xa0)
    8111
                m6 := mload(0xc0)
    8112
                m7 := mload(0xe0)
    8113
                m8 := mload(0x100)
    8114
                m9 := mload(0x120)
    8115
                m10 := mload(0x140)
    8116
                // Selector of `log(bool,string,string,string)`.
    8117
                mstore(0x00, 0x1762e32a)
    8118
                mstore(0x20, p0)
    8119
                mstore(0x40, 0x80)
    8120
                mstore(0x60, 0xc0)
    8121
                mstore(0x80, 0x100)
    8122
                writeString(0xa0, p1)
    8123
                writeString(0xe0, p2)
    8124
                writeString(0x120, p3)
    8125
            }
    8126
            _sendLogPayload(0x1c, 0x144);
    8127
            /// @solidity memory-safe-assembly
    8128
            assembly {
    8129
                mstore(0x00, m0)
    8130
                mstore(0x20, m1)
    8131
                mstore(0x40, m2)
    8132
                mstore(0x60, m3)
    8133
                mstore(0x80, m4)
    8134
                mstore(0xa0, m5)
    8135
                mstore(0xc0, m6)
    8136
                mstore(0xe0, m7)
    8137
                mstore(0x100, m8)
    8138
                mstore(0x120, m9)
    8139
                mstore(0x140, m10)
    8140
            }
    8141
        }
    8142
    8143
        function log(uint256 p0, address p1, address p2, address p3) internal pure {
    8144
            bytes32 m0;
    8145
            bytes32 m1;
    8146
            bytes32 m2;
    8147
            bytes32 m3;
    8148
            bytes32 m4;
    8149
            /// @solidity memory-safe-assembly
    8150
            assembly {
    8151
                m0 := mload(0x00)
    8152
                m1 := mload(0x20)
    8153
                m2 := mload(0x40)
    8154
                m3 := mload(0x60)
    8155
                m4 := mload(0x80)
    8156
                // Selector of `log(uint256,address,address,address)`.
    8157
                mstore(0x00, 0x2488b414)
    8158
                mstore(0x20, p0)
    8159
                mstore(0x40, p1)
    8160
                mstore(0x60, p2)
    8161
                mstore(0x80, p3)
    8162
            }
    8163
            _sendLogPayload(0x1c, 0x84);
    8164
            /// @solidity memory-safe-assembly
    8165
            assembly {
    8166
                mstore(0x00, m0)
    8167
                mstore(0x20, m1)
    8168
                mstore(0x40, m2)
    8169
                mstore(0x60, m3)
    8170
                mstore(0x80, m4)
    8171
            }
    8172
        }
    8173
    8174
        function log(uint256 p0, address p1, address p2, bool p3) internal pure {
    8175
            bytes32 m0;
    8176
            bytes32 m1;
    8177
            bytes32 m2;
    8178
            bytes32 m3;
    8179
            bytes32 m4;
    8180
            /// @solidity memory-safe-assembly
    8181
            assembly {
    8182
                m0 := mload(0x00)
    8183
                m1 := mload(0x20)
    8184
                m2 := mload(0x40)
    8185
                m3 := mload(0x60)
    8186
                m4 := mload(0x80)
    8187
                // Selector of `log(uint256,address,address,bool)`.
    8188
                mstore(0x00, 0x091ffaf5)
    8189
                mstore(0x20, p0)
    8190
                mstore(0x40, p1)
    8191
                mstore(0x60, p2)
    8192
                mstore(0x80, p3)
    8193
            }
    8194
            _sendLogPayload(0x1c, 0x84);
    8195
            /// @solidity memory-safe-assembly
    8196
            assembly {
    8197
                mstore(0x00, m0)
    8198
                mstore(0x20, m1)
    8199
                mstore(0x40, m2)
    8200
                mstore(0x60, m3)
    8201
                mstore(0x80, m4)
    8202
            }
    8203
        }
    8204
    8205
        function log(uint256 p0, address p1, address p2, uint256 p3) internal pure {
    8206
            bytes32 m0;
    8207
            bytes32 m1;
    8208
            bytes32 m2;
    8209
            bytes32 m3;
    8210
            bytes32 m4;
    8211
            /// @solidity memory-safe-assembly
    8212
            assembly {
    8213
                m0 := mload(0x00)
    8214
                m1 := mload(0x20)
    8215
                m2 := mload(0x40)
    8216
                m3 := mload(0x60)
    8217
                m4 := mload(0x80)
    8218
                // Selector of `log(uint256,address,address,uint256)`.
    8219
                mstore(0x00, 0x736efbb6)
    8220
                mstore(0x20, p0)
    8221
                mstore(0x40, p1)
    8222
                mstore(0x60, p2)
    8223
                mstore(0x80, p3)
    8224
            }
    8225
            _sendLogPayload(0x1c, 0x84);
    8226
            /// @solidity memory-safe-assembly
    8227
            assembly {
    8228
                mstore(0x00, m0)
    8229
                mstore(0x20, m1)
    8230
                mstore(0x40, m2)
    8231
                mstore(0x60, m3)
    8232
                mstore(0x80, m4)
    8233
            }
    8234
        }
    8235
    8236
        function log(uint256 p0, address p1, address p2, bytes32 p3) internal pure {
    8237
            bytes32 m0;
    8238
            bytes32 m1;
    8239
            bytes32 m2;
    8240
            bytes32 m3;
    8241
            bytes32 m4;
    8242
            bytes32 m5;
    8243
            bytes32 m6;
    8244
            /// @solidity memory-safe-assembly
    8245
            assembly {
    8246
                function writeString(pos, w) {
    8247
                    let length := 0
    8248
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    8249
                    mstore(pos, length)
    8250
                    let shift := sub(256, shl(3, length))
    8251
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    8252
                }
    8253
                m0 := mload(0x00)
    8254
                m1 := mload(0x20)
    8255
                m2 := mload(0x40)
    8256
                m3 := mload(0x60)
    8257
                m4 := mload(0x80)
    8258
                m5 := mload(0xa0)
    8259
                m6 := mload(0xc0)
    8260
                // Selector of `log(uint256,address,address,string)`.
    8261
                mstore(0x00, 0x031c6f73)
    8262
                mstore(0x20, p0)
    8263
                mstore(0x40, p1)
    8264
                mstore(0x60, p2)
    8265
                mstore(0x80, 0x80)
    8266
                writeString(0xa0, p3)
    8267
            }
    8268
            _sendLogPayload(0x1c, 0xc4);
    8269
            /// @solidity memory-safe-assembly
    8270
            assembly {
    8271
                mstore(0x00, m0)
    8272
                mstore(0x20, m1)
    8273
                mstore(0x40, m2)
    8274
                mstore(0x60, m3)
    8275
                mstore(0x80, m4)
    8276
                mstore(0xa0, m5)
    8277
                mstore(0xc0, m6)
    8278
            }
    8279
        }
    8280
    8281
        function log(uint256 p0, address p1, bool p2, address p3) internal pure {
    8282
            bytes32 m0;
    8283
            bytes32 m1;
    8284
            bytes32 m2;
    8285
            bytes32 m3;
    8286
            bytes32 m4;
    8287
            /// @solidity memory-safe-assembly
    8288
            assembly {
    8289
                m0 := mload(0x00)
    8290
                m1 := mload(0x20)
    8291
                m2 := mload(0x40)
    8292
                m3 := mload(0x60)
    8293
                m4 := mload(0x80)
    8294
                // Selector of `log(uint256,address,bool,address)`.
    8295
                mstore(0x00, 0xef72c513)
    8296
                mstore(0x20, p0)
    8297
                mstore(0x40, p1)
    8298
                mstore(0x60, p2)
    8299
                mstore(0x80, p3)
    8300
            }
    8301
            _sendLogPayload(0x1c, 0x84);
    8302
            /// @solidity memory-safe-assembly
    8303
            assembly {
    8304
                mstore(0x00, m0)
    8305
                mstore(0x20, m1)
    8306
                mstore(0x40, m2)
    8307
                mstore(0x60, m3)
    8308
                mstore(0x80, m4)
    8309
            }
    8310
        }
    8311
    8312
        function log(uint256 p0, address p1, bool p2, bool p3) internal pure {
    8313
            bytes32 m0;
    8314
            bytes32 m1;
    8315
            bytes32 m2;
    8316
            bytes32 m3;
    8317
            bytes32 m4;
    8318
            /// @solidity memory-safe-assembly
    8319
            assembly {
    8320
                m0 := mload(0x00)
    8321
                m1 := mload(0x20)
    8322
                m2 := mload(0x40)
    8323
                m3 := mload(0x60)
    8324
                m4 := mload(0x80)
    8325
                // Selector of `log(uint256,address,bool,bool)`.
    8326
                mstore(0x00, 0xe351140f)
    8327
                mstore(0x20, p0)
    8328
                mstore(0x40, p1)
    8329
                mstore(0x60, p2)
    8330
                mstore(0x80, p3)
    8331
            }
    8332
            _sendLogPayload(0x1c, 0x84);
    8333
            /// @solidity memory-safe-assembly
    8334
            assembly {
    8335
                mstore(0x00, m0)
    8336
                mstore(0x20, m1)
    8337
                mstore(0x40, m2)
    8338
                mstore(0x60, m3)
    8339
                mstore(0x80, m4)
    8340
            }
    8341
        }
    8342
    8343
        function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure {
    8344
            bytes32 m0;
    8345
            bytes32 m1;
    8346
            bytes32 m2;
    8347
            bytes32 m3;
    8348
            bytes32 m4;
    8349
            /// @solidity memory-safe-assembly
    8350
            assembly {
    8351
                m0 := mload(0x00)
    8352
                m1 := mload(0x20)
    8353
                m2 := mload(0x40)
    8354
                m3 := mload(0x60)
    8355
                m4 := mload(0x80)
    8356
                // Selector of `log(uint256,address,bool,uint256)`.
    8357
                mstore(0x00, 0x5abd992a)
    8358
                mstore(0x20, p0)
    8359
                mstore(0x40, p1)
    8360
                mstore(0x60, p2)
    8361
                mstore(0x80, p3)
    8362
            }
    8363
            _sendLogPayload(0x1c, 0x84);
    8364
            /// @solidity memory-safe-assembly
    8365
            assembly {
    8366
                mstore(0x00, m0)
    8367
                mstore(0x20, m1)
    8368
                mstore(0x40, m2)
    8369
                mstore(0x60, m3)
    8370
                mstore(0x80, m4)
    8371
            }
    8372
        }
    8373
    8374
        function log(uint256 p0, address p1, bool p2, bytes32 p3) internal pure {
    8375
            bytes32 m0;
    8376
            bytes32 m1;
    8377
            bytes32 m2;
    8378
            bytes32 m3;
    8379
            bytes32 m4;
    8380
            bytes32 m5;
    8381
            bytes32 m6;
    8382
            /// @solidity memory-safe-assembly
    8383
            assembly {
    8384
                function writeString(pos, w) {
    8385
                    let length := 0
    8386
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    8387
                    mstore(pos, length)
    8388
                    let shift := sub(256, shl(3, length))
    8389
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    8390
                }
    8391
                m0 := mload(0x00)
    8392
                m1 := mload(0x20)
    8393
                m2 := mload(0x40)
    8394
                m3 := mload(0x60)
    8395
                m4 := mload(0x80)
    8396
                m5 := mload(0xa0)
    8397
                m6 := mload(0xc0)
    8398
                // Selector of `log(uint256,address,bool,string)`.
    8399
                mstore(0x00, 0x90fb06aa)
    8400
                mstore(0x20, p0)
    8401
                mstore(0x40, p1)
    8402
                mstore(0x60, p2)
    8403
                mstore(0x80, 0x80)
    8404
                writeString(0xa0, p3)
    8405
            }
    8406
            _sendLogPayload(0x1c, 0xc4);
    8407
            /// @solidity memory-safe-assembly
    8408
            assembly {
    8409
                mstore(0x00, m0)
    8410
                mstore(0x20, m1)
    8411
                mstore(0x40, m2)
    8412
                mstore(0x60, m3)
    8413
                mstore(0x80, m4)
    8414
                mstore(0xa0, m5)
    8415
                mstore(0xc0, m6)
    8416
            }
    8417
        }
    8418
    8419
        function log(uint256 p0, address p1, uint256 p2, address p3) internal pure {
    8420
            bytes32 m0;
    8421
            bytes32 m1;
    8422
            bytes32 m2;
    8423
            bytes32 m3;
    8424
            bytes32 m4;
    8425
            /// @solidity memory-safe-assembly
    8426
            assembly {
    8427
                m0 := mload(0x00)
    8428
                m1 := mload(0x20)
    8429
                m2 := mload(0x40)
    8430
                m3 := mload(0x60)
    8431
                m4 := mload(0x80)
    8432
                // Selector of `log(uint256,address,uint256,address)`.
    8433
                mstore(0x00, 0x15c127b5)
    8434
                mstore(0x20, p0)
    8435
                mstore(0x40, p1)
    8436
                mstore(0x60, p2)
    8437
                mstore(0x80, p3)
    8438
            }
    8439
            _sendLogPayload(0x1c, 0x84);
    8440
            /// @solidity memory-safe-assembly
    8441
            assembly {
    8442
                mstore(0x00, m0)
    8443
                mstore(0x20, m1)
    8444
                mstore(0x40, m2)
    8445
                mstore(0x60, m3)
    8446
                mstore(0x80, m4)
    8447
            }
    8448
        }
    8449
    8450
        function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure {
    8451
            bytes32 m0;
    8452
            bytes32 m1;
    8453
            bytes32 m2;
    8454
            bytes32 m3;
    8455
            bytes32 m4;
    8456
            /// @solidity memory-safe-assembly
    8457
            assembly {
    8458
                m0 := mload(0x00)
    8459
                m1 := mload(0x20)
    8460
                m2 := mload(0x40)
    8461
                m3 := mload(0x60)
    8462
                m4 := mload(0x80)
    8463
                // Selector of `log(uint256,address,uint256,bool)`.
    8464
                mstore(0x00, 0x5f743a7c)
    8465
                mstore(0x20, p0)
    8466
                mstore(0x40, p1)
    8467
                mstore(0x60, p2)
    8468
                mstore(0x80, p3)
    8469
            }
    8470
            _sendLogPayload(0x1c, 0x84);
    8471
            /// @solidity memory-safe-assembly
    8472
            assembly {
    8473
                mstore(0x00, m0)
    8474
                mstore(0x20, m1)
    8475
                mstore(0x40, m2)
    8476
                mstore(0x60, m3)
    8477
                mstore(0x80, m4)
    8478
            }
    8479
        }
    8480
    8481
        function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure {
    8482
            bytes32 m0;
    8483
            bytes32 m1;
    8484
            bytes32 m2;
    8485
            bytes32 m3;
    8486
            bytes32 m4;
    8487
            /// @solidity memory-safe-assembly
    8488
            assembly {
    8489
                m0 := mload(0x00)
    8490
                m1 := mload(0x20)
    8491
                m2 := mload(0x40)
    8492
                m3 := mload(0x60)
    8493
                m4 := mload(0x80)
    8494
                // Selector of `log(uint256,address,uint256,uint256)`.
    8495
                mstore(0x00, 0x0c9cd9c1)
    8496
                mstore(0x20, p0)
    8497
                mstore(0x40, p1)
    8498
                mstore(0x60, p2)
    8499
                mstore(0x80, p3)
    8500
            }
    8501
            _sendLogPayload(0x1c, 0x84);
    8502
            /// @solidity memory-safe-assembly
    8503
            assembly {
    8504
                mstore(0x00, m0)
    8505
                mstore(0x20, m1)
    8506
                mstore(0x40, m2)
    8507
                mstore(0x60, m3)
    8508
                mstore(0x80, m4)
    8509
            }
    8510
        }
    8511
    8512
        function log(uint256 p0, address p1, uint256 p2, bytes32 p3) internal pure {
    8513
            bytes32 m0;
    8514
            bytes32 m1;
    8515
            bytes32 m2;
    8516
            bytes32 m3;
    8517
            bytes32 m4;
    8518
            bytes32 m5;
    8519
            bytes32 m6;
    8520
            /// @solidity memory-safe-assembly
    8521
            assembly {
    8522
                function writeString(pos, w) {
    8523
                    let length := 0
    8524
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    8525
                    mstore(pos, length)
    8526
                    let shift := sub(256, shl(3, length))
    8527
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    8528
                }
    8529
                m0 := mload(0x00)
    8530
                m1 := mload(0x20)
    8531
                m2 := mload(0x40)
    8532
                m3 := mload(0x60)
    8533
                m4 := mload(0x80)
    8534
                m5 := mload(0xa0)
    8535
                m6 := mload(0xc0)
    8536
                // Selector of `log(uint256,address,uint256,string)`.
    8537
                mstore(0x00, 0xddb06521)
    8538
                mstore(0x20, p0)
    8539
                mstore(0x40, p1)
    8540
                mstore(0x60, p2)
    8541
                mstore(0x80, 0x80)
    8542
                writeString(0xa0, p3)
    8543
            }
    8544
            _sendLogPayload(0x1c, 0xc4);
    8545
            /// @solidity memory-safe-assembly
    8546
            assembly {
    8547
                mstore(0x00, m0)
    8548
                mstore(0x20, m1)
    8549
                mstore(0x40, m2)
    8550
                mstore(0x60, m3)
    8551
                mstore(0x80, m4)
    8552
                mstore(0xa0, m5)
    8553
                mstore(0xc0, m6)
    8554
            }
    8555
        }
    8556
    8557
        function log(uint256 p0, address p1, bytes32 p2, address p3) internal pure {
    8558
            bytes32 m0;
    8559
            bytes32 m1;
    8560
            bytes32 m2;
    8561
            bytes32 m3;
    8562
            bytes32 m4;
    8563
            bytes32 m5;
    8564
            bytes32 m6;
    8565
            /// @solidity memory-safe-assembly
    8566
            assembly {
    8567
                function writeString(pos, w) {
    8568
                    let length := 0
    8569
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    8570
                    mstore(pos, length)
    8571
                    let shift := sub(256, shl(3, length))
    8572
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    8573
                }
    8574
                m0 := mload(0x00)
    8575
                m1 := mload(0x20)
    8576
                m2 := mload(0x40)
    8577
                m3 := mload(0x60)
    8578
                m4 := mload(0x80)
    8579
                m5 := mload(0xa0)
    8580
                m6 := mload(0xc0)
    8581
                // Selector of `log(uint256,address,string,address)`.
    8582
                mstore(0x00, 0x9cba8fff)
    8583
                mstore(0x20, p0)
    8584
                mstore(0x40, p1)
    8585
                mstore(0x60, 0x80)
    8586
                mstore(0x80, p3)
    8587
                writeString(0xa0, p2)
    8588
            }
    8589
            _sendLogPayload(0x1c, 0xc4);
    8590
            /// @solidity memory-safe-assembly
    8591
            assembly {
    8592
                mstore(0x00, m0)
    8593
                mstore(0x20, m1)
    8594
                mstore(0x40, m2)
    8595
                mstore(0x60, m3)
    8596
                mstore(0x80, m4)
    8597
                mstore(0xa0, m5)
    8598
                mstore(0xc0, m6)
    8599
            }
    8600
        }
    8601
    8602
        function log(uint256 p0, address p1, bytes32 p2, bool p3) internal pure {
    8603
            bytes32 m0;
    8604
            bytes32 m1;
    8605
            bytes32 m2;
    8606
            bytes32 m3;
    8607
            bytes32 m4;
    8608
            bytes32 m5;
    8609
            bytes32 m6;
    8610
            /// @solidity memory-safe-assembly
    8611
            assembly {
    8612
                function writeString(pos, w) {
    8613
                    let length := 0
    8614
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    8615
                    mstore(pos, length)
    8616
                    let shift := sub(256, shl(3, length))
    8617
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    8618
                }
    8619
                m0 := mload(0x00)
    8620
                m1 := mload(0x20)
    8621
                m2 := mload(0x40)
    8622
                m3 := mload(0x60)
    8623
                m4 := mload(0x80)
    8624
                m5 := mload(0xa0)
    8625
                m6 := mload(0xc0)
    8626
                // Selector of `log(uint256,address,string,bool)`.
    8627
                mstore(0x00, 0xcc32ab07)
    8628
                mstore(0x20, p0)
    8629
                mstore(0x40, p1)
    8630
                mstore(0x60, 0x80)
    8631
                mstore(0x80, p3)
    8632
                writeString(0xa0, p2)
    8633
            }
    8634
            _sendLogPayload(0x1c, 0xc4);
    8635
            /// @solidity memory-safe-assembly
    8636
            assembly {
    8637
                mstore(0x00, m0)
    8638
                mstore(0x20, m1)
    8639
                mstore(0x40, m2)
    8640
                mstore(0x60, m3)
    8641
                mstore(0x80, m4)
    8642
                mstore(0xa0, m5)
    8643
                mstore(0xc0, m6)
    8644
            }
    8645
        }
    8646
    8647
        function log(uint256 p0, address p1, bytes32 p2, uint256 p3) internal pure {
    8648
            bytes32 m0;
    8649
            bytes32 m1;
    8650
            bytes32 m2;
    8651
            bytes32 m3;
    8652
            bytes32 m4;
    8653
            bytes32 m5;
    8654
            bytes32 m6;
    8655
            /// @solidity memory-safe-assembly
    8656
            assembly {
    8657
                function writeString(pos, w) {
    8658
                    let length := 0
    8659
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    8660
                    mstore(pos, length)
    8661
                    let shift := sub(256, shl(3, length))
    8662
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    8663
                }
    8664
                m0 := mload(0x00)
    8665
                m1 := mload(0x20)
    8666
                m2 := mload(0x40)
    8667
                m3 := mload(0x60)
    8668
                m4 := mload(0x80)
    8669
                m5 := mload(0xa0)
    8670
                m6 := mload(0xc0)
    8671
                // Selector of `log(uint256,address,string,uint256)`.
    8672
                mstore(0x00, 0x46826b5d)
    8673
                mstore(0x20, p0)
    8674
                mstore(0x40, p1)
    8675
                mstore(0x60, 0x80)
    8676
                mstore(0x80, p3)
    8677
                writeString(0xa0, p2)
    8678
            }
    8679
            _sendLogPayload(0x1c, 0xc4);
    8680
            /// @solidity memory-safe-assembly
    8681
            assembly {
    8682
                mstore(0x00, m0)
    8683
                mstore(0x20, m1)
    8684
                mstore(0x40, m2)
    8685
                mstore(0x60, m3)
    8686
                mstore(0x80, m4)
    8687
                mstore(0xa0, m5)
    8688
                mstore(0xc0, m6)
    8689
            }
    8690
        }
    8691
    8692
        function log(uint256 p0, address p1, bytes32 p2, bytes32 p3) internal pure {
    8693
            bytes32 m0;
    8694
            bytes32 m1;
    8695
            bytes32 m2;
    8696
            bytes32 m3;
    8697
            bytes32 m4;
    8698
            bytes32 m5;
    8699
            bytes32 m6;
    8700
            bytes32 m7;
    8701
            bytes32 m8;
    8702
            /// @solidity memory-safe-assembly
    8703
            assembly {
    8704
                function writeString(pos, w) {
    8705
                    let length := 0
    8706
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    8707
                    mstore(pos, length)
    8708
                    let shift := sub(256, shl(3, length))
    8709
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    8710
                }
    8711
                m0 := mload(0x00)
    8712
                m1 := mload(0x20)
    8713
                m2 := mload(0x40)
    8714
                m3 := mload(0x60)
    8715
                m4 := mload(0x80)
    8716
                m5 := mload(0xa0)
    8717
                m6 := mload(0xc0)
    8718
                m7 := mload(0xe0)
    8719
                m8 := mload(0x100)
    8720
                // Selector of `log(uint256,address,string,string)`.
    8721
                mstore(0x00, 0x3e128ca3)
    8722
                mstore(0x20, p0)
    8723
                mstore(0x40, p1)
    8724
                mstore(0x60, 0x80)
    8725
                mstore(0x80, 0xc0)
    8726
                writeString(0xa0, p2)
    8727
                writeString(0xe0, p3)
    8728
            }
    8729
            _sendLogPayload(0x1c, 0x104);
    8730
            /// @solidity memory-safe-assembly
    8731
            assembly {
    8732
                mstore(0x00, m0)
    8733
                mstore(0x20, m1)
    8734
                mstore(0x40, m2)
    8735
                mstore(0x60, m3)
    8736
                mstore(0x80, m4)
    8737
                mstore(0xa0, m5)
    8738
                mstore(0xc0, m6)
    8739
                mstore(0xe0, m7)
    8740
                mstore(0x100, m8)
    8741
            }
    8742
        }
    8743
    8744
        function log(uint256 p0, bool p1, address p2, address p3) internal pure {
    8745
            bytes32 m0;
    8746
            bytes32 m1;
    8747
            bytes32 m2;
    8748
            bytes32 m3;
    8749
            bytes32 m4;
    8750
            /// @solidity memory-safe-assembly
    8751
            assembly {
    8752
                m0 := mload(0x00)
    8753
                m1 := mload(0x20)
    8754
                m2 := mload(0x40)
    8755
                m3 := mload(0x60)
    8756
                m4 := mload(0x80)
    8757
                // Selector of `log(uint256,bool,address,address)`.
    8758
                mstore(0x00, 0xa1ef4cbb)
    8759
                mstore(0x20, p0)
    8760
                mstore(0x40, p1)
    8761
                mstore(0x60, p2)
    8762
                mstore(0x80, p3)
    8763
            }
    8764
            _sendLogPayload(0x1c, 0x84);
    8765
            /// @solidity memory-safe-assembly
    8766
            assembly {
    8767
                mstore(0x00, m0)
    8768
                mstore(0x20, m1)
    8769
                mstore(0x40, m2)
    8770
                mstore(0x60, m3)
    8771
                mstore(0x80, m4)
    8772
            }
    8773
        }
    8774
    8775
        function log(uint256 p0, bool p1, address p2, bool p3) internal pure {
    8776
            bytes32 m0;
    8777
            bytes32 m1;
    8778
            bytes32 m2;
    8779
            bytes32 m3;
    8780
            bytes32 m4;
    8781
            /// @solidity memory-safe-assembly
    8782
            assembly {
    8783
                m0 := mload(0x00)
    8784
                m1 := mload(0x20)
    8785
                m2 := mload(0x40)
    8786
                m3 := mload(0x60)
    8787
                m4 := mload(0x80)
    8788
                // Selector of `log(uint256,bool,address,bool)`.
    8789
                mstore(0x00, 0x454d54a5)
    8790
                mstore(0x20, p0)
    8791
                mstore(0x40, p1)
    8792
                mstore(0x60, p2)
    8793
                mstore(0x80, p3)
    8794
            }
    8795
            _sendLogPayload(0x1c, 0x84);
    8796
            /// @solidity memory-safe-assembly
    8797
            assembly {
    8798
                mstore(0x00, m0)
    8799
                mstore(0x20, m1)
    8800
                mstore(0x40, m2)
    8801
                mstore(0x60, m3)
    8802
                mstore(0x80, m4)
    8803
            }
    8804
        }
    8805
    8806
        function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure {
    8807
            bytes32 m0;
    8808
            bytes32 m1;
    8809
            bytes32 m2;
    8810
            bytes32 m3;
    8811
            bytes32 m4;
    8812
            /// @solidity memory-safe-assembly
    8813
            assembly {
    8814
                m0 := mload(0x00)
    8815
                m1 := mload(0x20)
    8816
                m2 := mload(0x40)
    8817
                m3 := mload(0x60)
    8818
                m4 := mload(0x80)
    8819
                // Selector of `log(uint256,bool,address,uint256)`.
    8820
                mstore(0x00, 0x078287f5)
    8821
                mstore(0x20, p0)
    8822
                mstore(0x40, p1)
    8823
                mstore(0x60, p2)
    8824
                mstore(0x80, p3)
    8825
            }
    8826
            _sendLogPayload(0x1c, 0x84);
    8827
            /// @solidity memory-safe-assembly
    8828
            assembly {
    8829
                mstore(0x00, m0)
    8830
                mstore(0x20, m1)
    8831
                mstore(0x40, m2)
    8832
                mstore(0x60, m3)
    8833
                mstore(0x80, m4)
    8834
            }
    8835
        }
    8836
    8837
        function log(uint256 p0, bool p1, address p2, bytes32 p3) internal pure {
    8838
            bytes32 m0;
    8839
            bytes32 m1;
    8840
            bytes32 m2;
    8841
            bytes32 m3;
    8842
            bytes32 m4;
    8843
            bytes32 m5;
    8844
            bytes32 m6;
    8845
            /// @solidity memory-safe-assembly
    8846
            assembly {
    8847
                function writeString(pos, w) {
    8848
                    let length := 0
    8849
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    8850
                    mstore(pos, length)
    8851
                    let shift := sub(256, shl(3, length))
    8852
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    8853
                }
    8854
                m0 := mload(0x00)
    8855
                m1 := mload(0x20)
    8856
                m2 := mload(0x40)
    8857
                m3 := mload(0x60)
    8858
                m4 := mload(0x80)
    8859
                m5 := mload(0xa0)
    8860
                m6 := mload(0xc0)
    8861
                // Selector of `log(uint256,bool,address,string)`.
    8862
                mstore(0x00, 0xade052c7)
    8863
                mstore(0x20, p0)
    8864
                mstore(0x40, p1)
    8865
                mstore(0x60, p2)
    8866
                mstore(0x80, 0x80)
    8867
                writeString(0xa0, p3)
    8868
            }
    8869
            _sendLogPayload(0x1c, 0xc4);
    8870
            /// @solidity memory-safe-assembly
    8871
            assembly {
    8872
                mstore(0x00, m0)
    8873
                mstore(0x20, m1)
    8874
                mstore(0x40, m2)
    8875
                mstore(0x60, m3)
    8876
                mstore(0x80, m4)
    8877
                mstore(0xa0, m5)
    8878
                mstore(0xc0, m6)
    8879
            }
    8880
        }
    8881
    8882
        function log(uint256 p0, bool p1, bool p2, address p3) internal pure {
    8883
            bytes32 m0;
    8884
            bytes32 m1;
    8885
            bytes32 m2;
    8886
            bytes32 m3;
    8887
            bytes32 m4;
    8888
            /// @solidity memory-safe-assembly
    8889
            assembly {
    8890
                m0 := mload(0x00)
    8891
                m1 := mload(0x20)
    8892
                m2 := mload(0x40)
    8893
                m3 := mload(0x60)
    8894
                m4 := mload(0x80)
    8895
                // Selector of `log(uint256,bool,bool,address)`.
    8896
                mstore(0x00, 0x69640b59)
    8897
                mstore(0x20, p0)
    8898
                mstore(0x40, p1)
    8899
                mstore(0x60, p2)
    8900
                mstore(0x80, p3)
    8901
            }
    8902
            _sendLogPayload(0x1c, 0x84);
    8903
            /// @solidity memory-safe-assembly
    8904
            assembly {
    8905
                mstore(0x00, m0)
    8906
                mstore(0x20, m1)
    8907
                mstore(0x40, m2)
    8908
                mstore(0x60, m3)
    8909
                mstore(0x80, m4)
    8910
            }
    8911
        }
    8912
    8913
        function log(uint256 p0, bool p1, bool p2, bool p3) internal pure {
    8914
            bytes32 m0;
    8915
            bytes32 m1;
    8916
            bytes32 m2;
    8917
            bytes32 m3;
    8918
            bytes32 m4;
    8919
            /// @solidity memory-safe-assembly
    8920
            assembly {
    8921
                m0 := mload(0x00)
    8922
                m1 := mload(0x20)
    8923
                m2 := mload(0x40)
    8924
                m3 := mload(0x60)
    8925
                m4 := mload(0x80)
    8926
                // Selector of `log(uint256,bool,bool,bool)`.
    8927
                mstore(0x00, 0xb6f577a1)
    8928
                mstore(0x20, p0)
    8929
                mstore(0x40, p1)
    8930
                mstore(0x60, p2)
    8931
                mstore(0x80, p3)
    8932
            }
    8933
            _sendLogPayload(0x1c, 0x84);
    8934
            /// @solidity memory-safe-assembly
    8935
            assembly {
    8936
                mstore(0x00, m0)
    8937
                mstore(0x20, m1)
    8938
                mstore(0x40, m2)
    8939
                mstore(0x60, m3)
    8940
                mstore(0x80, m4)
    8941
            }
    8942
        }
    8943
    8944
        function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure {
    8945
            bytes32 m0;
    8946
            bytes32 m1;
    8947
            bytes32 m2;
    8948
            bytes32 m3;
    8949
            bytes32 m4;
    8950
            /// @solidity memory-safe-assembly
    8951
            assembly {
    8952
                m0 := mload(0x00)
    8953
                m1 := mload(0x20)
    8954
                m2 := mload(0x40)
    8955
                m3 := mload(0x60)
    8956
                m4 := mload(0x80)
    8957
                // Selector of `log(uint256,bool,bool,uint256)`.
    8958
                mstore(0x00, 0x7464ce23)
    8959
                mstore(0x20, p0)
    8960
                mstore(0x40, p1)
    8961
                mstore(0x60, p2)
    8962
                mstore(0x80, p3)
    8963
            }
    8964
            _sendLogPayload(0x1c, 0x84);
    8965
            /// @solidity memory-safe-assembly
    8966
            assembly {
    8967
                mstore(0x00, m0)
    8968
                mstore(0x20, m1)
    8969
                mstore(0x40, m2)
    8970
                mstore(0x60, m3)
    8971
                mstore(0x80, m4)
    8972
            }
    8973
        }
    8974
    8975
        function log(uint256 p0, bool p1, bool p2, bytes32 p3) internal pure {
    8976
            bytes32 m0;
    8977
            bytes32 m1;
    8978
            bytes32 m2;
    8979
            bytes32 m3;
    8980
            bytes32 m4;
    8981
            bytes32 m5;
    8982
            bytes32 m6;
    8983
            /// @solidity memory-safe-assembly
    8984
            assembly {
    8985
                function writeString(pos, w) {
    8986
                    let length := 0
    8987
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    8988
                    mstore(pos, length)
    8989
                    let shift := sub(256, shl(3, length))
    8990
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    8991
                }
    8992
                m0 := mload(0x00)
    8993
                m1 := mload(0x20)
    8994
                m2 := mload(0x40)
    8995
                m3 := mload(0x60)
    8996
                m4 := mload(0x80)
    8997
                m5 := mload(0xa0)
    8998
                m6 := mload(0xc0)
    8999
                // Selector of `log(uint256,bool,bool,string)`.
    9000
                mstore(0x00, 0xdddb9561)
    9001
                mstore(0x20, p0)
    9002
                mstore(0x40, p1)
    9003
                mstore(0x60, p2)
    9004
                mstore(0x80, 0x80)
    9005
                writeString(0xa0, p3)
    9006
            }
    9007
            _sendLogPayload(0x1c, 0xc4);
    9008
            /// @solidity memory-safe-assembly
    9009
            assembly {
    9010
                mstore(0x00, m0)
    9011
                mstore(0x20, m1)
    9012
                mstore(0x40, m2)
    9013
                mstore(0x60, m3)
    9014
                mstore(0x80, m4)
    9015
                mstore(0xa0, m5)
    9016
                mstore(0xc0, m6)
    9017
            }
    9018
        }
    9019
    9020
        function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure {
    9021
            bytes32 m0;
    9022
            bytes32 m1;
    9023
            bytes32 m2;
    9024
            bytes32 m3;
    9025
            bytes32 m4;
    9026
            /// @solidity memory-safe-assembly
    9027
            assembly {
    9028
                m0 := mload(0x00)
    9029
                m1 := mload(0x20)
    9030
                m2 := mload(0x40)
    9031
                m3 := mload(0x60)
    9032
                m4 := mload(0x80)
    9033
                // Selector of `log(uint256,bool,uint256,address)`.
    9034
                mstore(0x00, 0x88cb6041)
    9035
                mstore(0x20, p0)
    9036
                mstore(0x40, p1)
    9037
                mstore(0x60, p2)
    9038
                mstore(0x80, p3)
    9039
            }
    9040
            _sendLogPayload(0x1c, 0x84);
    9041
            /// @solidity memory-safe-assembly
    9042
            assembly {
    9043
                mstore(0x00, m0)
    9044
                mstore(0x20, m1)
    9045
                mstore(0x40, m2)
    9046
                mstore(0x60, m3)
    9047
                mstore(0x80, m4)
    9048
            }
    9049
        }
    9050
    9051
        function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure {
    9052
            bytes32 m0;
    9053
            bytes32 m1;
    9054
            bytes32 m2;
    9055
            bytes32 m3;
    9056
            bytes32 m4;
    9057
            /// @solidity memory-safe-assembly
    9058
            assembly {
    9059
                m0 := mload(0x00)
    9060
                m1 := mload(0x20)
    9061
                m2 := mload(0x40)
    9062
                m3 := mload(0x60)
    9063
                m4 := mload(0x80)
    9064
                // Selector of `log(uint256,bool,uint256,bool)`.
    9065
                mstore(0x00, 0x91a02e2a)
    9066
                mstore(0x20, p0)
    9067
                mstore(0x40, p1)
    9068
                mstore(0x60, p2)
    9069
                mstore(0x80, p3)
    9070
            }
    9071
            _sendLogPayload(0x1c, 0x84);
    9072
            /// @solidity memory-safe-assembly
    9073
            assembly {
    9074
                mstore(0x00, m0)
    9075
                mstore(0x20, m1)
    9076
                mstore(0x40, m2)
    9077
                mstore(0x60, m3)
    9078
                mstore(0x80, m4)
    9079
            }
    9080
        }
    9081
    9082
        function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure {
    9083
            bytes32 m0;
    9084
            bytes32 m1;
    9085
            bytes32 m2;
    9086
            bytes32 m3;
    9087
            bytes32 m4;
    9088
            /// @solidity memory-safe-assembly
    9089
            assembly {
    9090
                m0 := mload(0x00)
    9091
                m1 := mload(0x20)
    9092
                m2 := mload(0x40)
    9093
                m3 := mload(0x60)
    9094
                m4 := mload(0x80)
    9095
                // Selector of `log(uint256,bool,uint256,uint256)`.
    9096
                mstore(0x00, 0xc6acc7a8)
    9097
                mstore(0x20, p0)
    9098
                mstore(0x40, p1)
    9099
                mstore(0x60, p2)
    9100
                mstore(0x80, p3)
    9101
            }
    9102
            _sendLogPayload(0x1c, 0x84);
    9103
            /// @solidity memory-safe-assembly
    9104
            assembly {
    9105
                mstore(0x00, m0)
    9106
                mstore(0x20, m1)
    9107
                mstore(0x40, m2)
    9108
                mstore(0x60, m3)
    9109
                mstore(0x80, m4)
    9110
            }
    9111
        }
    9112
    9113
        function log(uint256 p0, bool p1, uint256 p2, bytes32 p3) internal pure {
    9114
            bytes32 m0;
    9115
            bytes32 m1;
    9116
            bytes32 m2;
    9117
            bytes32 m3;
    9118
            bytes32 m4;
    9119
            bytes32 m5;
    9120
            bytes32 m6;
    9121
            /// @solidity memory-safe-assembly
    9122
            assembly {
    9123
                function writeString(pos, w) {
    9124
                    let length := 0
    9125
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    9126
                    mstore(pos, length)
    9127
                    let shift := sub(256, shl(3, length))
    9128
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    9129
                }
    9130
                m0 := mload(0x00)
    9131
                m1 := mload(0x20)
    9132
                m2 := mload(0x40)
    9133
                m3 := mload(0x60)
    9134
                m4 := mload(0x80)
    9135
                m5 := mload(0xa0)
    9136
                m6 := mload(0xc0)
    9137
                // Selector of `log(uint256,bool,uint256,string)`.
    9138
                mstore(0x00, 0xde03e774)
    9139
                mstore(0x20, p0)
    9140
                mstore(0x40, p1)
    9141
                mstore(0x60, p2)
    9142
                mstore(0x80, 0x80)
    9143
                writeString(0xa0, p3)
    9144
            }
    9145
            _sendLogPayload(0x1c, 0xc4);
    9146
            /// @solidity memory-safe-assembly
    9147
            assembly {
    9148
                mstore(0x00, m0)
    9149
                mstore(0x20, m1)
    9150
                mstore(0x40, m2)
    9151
                mstore(0x60, m3)
    9152
                mstore(0x80, m4)
    9153
                mstore(0xa0, m5)
    9154
                mstore(0xc0, m6)
    9155
            }
    9156
        }
    9157
    9158
        function log(uint256 p0, bool p1, bytes32 p2, address p3) internal pure {
    9159
            bytes32 m0;
    9160
            bytes32 m1;
    9161
            bytes32 m2;
    9162
            bytes32 m3;
    9163
            bytes32 m4;
    9164
            bytes32 m5;
    9165
            bytes32 m6;
    9166
            /// @solidity memory-safe-assembly
    9167
            assembly {
    9168
                function writeString(pos, w) {
    9169
                    let length := 0
    9170
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    9171
                    mstore(pos, length)
    9172
                    let shift := sub(256, shl(3, length))
    9173
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    9174
                }
    9175
                m0 := mload(0x00)
    9176
                m1 := mload(0x20)
    9177
                m2 := mload(0x40)
    9178
                m3 := mload(0x60)
    9179
                m4 := mload(0x80)
    9180
                m5 := mload(0xa0)
    9181
                m6 := mload(0xc0)
    9182
                // Selector of `log(uint256,bool,string,address)`.
    9183
                mstore(0x00, 0xef529018)
    9184
                mstore(0x20, p0)
    9185
                mstore(0x40, p1)
    9186
                mstore(0x60, 0x80)
    9187
                mstore(0x80, p3)
    9188
                writeString(0xa0, p2)
    9189
            }
    9190
            _sendLogPayload(0x1c, 0xc4);
    9191
            /// @solidity memory-safe-assembly
    9192
            assembly {
    9193
                mstore(0x00, m0)
    9194
                mstore(0x20, m1)
    9195
                mstore(0x40, m2)
    9196
                mstore(0x60, m3)
    9197
                mstore(0x80, m4)
    9198
                mstore(0xa0, m5)
    9199
                mstore(0xc0, m6)
    9200
            }
    9201
        }
    9202
    9203
        function log(uint256 p0, bool p1, bytes32 p2, bool p3) internal pure {
    9204
            bytes32 m0;
    9205
            bytes32 m1;
    9206
            bytes32 m2;
    9207
            bytes32 m3;
    9208
            bytes32 m4;
    9209
            bytes32 m5;
    9210
            bytes32 m6;
    9211
            /// @solidity memory-safe-assembly
    9212
            assembly {
    9213
                function writeString(pos, w) {
    9214
                    let length := 0
    9215
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    9216
                    mstore(pos, length)
    9217
                    let shift := sub(256, shl(3, length))
    9218
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    9219
                }
    9220
                m0 := mload(0x00)
    9221
                m1 := mload(0x20)
    9222
                m2 := mload(0x40)
    9223
                m3 := mload(0x60)
    9224
                m4 := mload(0x80)
    9225
                m5 := mload(0xa0)
    9226
                m6 := mload(0xc0)
    9227
                // Selector of `log(uint256,bool,string,bool)`.
    9228
                mstore(0x00, 0xeb928d7f)
    9229
                mstore(0x20, p0)
    9230
                mstore(0x40, p1)
    9231
                mstore(0x60, 0x80)
    9232
                mstore(0x80, p3)
    9233
                writeString(0xa0, p2)
    9234
            }
    9235
            _sendLogPayload(0x1c, 0xc4);
    9236
            /// @solidity memory-safe-assembly
    9237
            assembly {
    9238
                mstore(0x00, m0)
    9239
                mstore(0x20, m1)
    9240
                mstore(0x40, m2)
    9241
                mstore(0x60, m3)
    9242
                mstore(0x80, m4)
    9243
                mstore(0xa0, m5)
    9244
                mstore(0xc0, m6)
    9245
            }
    9246
        }
    9247
    9248
        function log(uint256 p0, bool p1, bytes32 p2, uint256 p3) internal pure {
    9249
            bytes32 m0;
    9250
            bytes32 m1;
    9251
            bytes32 m2;
    9252
            bytes32 m3;
    9253
            bytes32 m4;
    9254
            bytes32 m5;
    9255
            bytes32 m6;
    9256
            /// @solidity memory-safe-assembly
    9257
            assembly {
    9258
                function writeString(pos, w) {
    9259
                    let length := 0
    9260
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    9261
                    mstore(pos, length)
    9262
                    let shift := sub(256, shl(3, length))
    9263
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    9264
                }
    9265
                m0 := mload(0x00)
    9266
                m1 := mload(0x20)
    9267
                m2 := mload(0x40)
    9268
                m3 := mload(0x60)
    9269
                m4 := mload(0x80)
    9270
                m5 := mload(0xa0)
    9271
                m6 := mload(0xc0)
    9272
                // Selector of `log(uint256,bool,string,uint256)`.
    9273
                mstore(0x00, 0x2c1d0746)
    9274
                mstore(0x20, p0)
    9275
                mstore(0x40, p1)
    9276
                mstore(0x60, 0x80)
    9277
                mstore(0x80, p3)
    9278
                writeString(0xa0, p2)
    9279
            }
    9280
            _sendLogPayload(0x1c, 0xc4);
    9281
            /// @solidity memory-safe-assembly
    9282
            assembly {
    9283
                mstore(0x00, m0)
    9284
                mstore(0x20, m1)
    9285
                mstore(0x40, m2)
    9286
                mstore(0x60, m3)
    9287
                mstore(0x80, m4)
    9288
                mstore(0xa0, m5)
    9289
                mstore(0xc0, m6)
    9290
            }
    9291
        }
    9292
    9293
        function log(uint256 p0, bool p1, bytes32 p2, bytes32 p3) internal pure {
    9294
            bytes32 m0;
    9295
            bytes32 m1;
    9296
            bytes32 m2;
    9297
            bytes32 m3;
    9298
            bytes32 m4;
    9299
            bytes32 m5;
    9300
            bytes32 m6;
    9301
            bytes32 m7;
    9302
            bytes32 m8;
    9303
            /// @solidity memory-safe-assembly
    9304
            assembly {
    9305
                function writeString(pos, w) {
    9306
                    let length := 0
    9307
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    9308
                    mstore(pos, length)
    9309
                    let shift := sub(256, shl(3, length))
    9310
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    9311
                }
    9312
                m0 := mload(0x00)
    9313
                m1 := mload(0x20)
    9314
                m2 := mload(0x40)
    9315
                m3 := mload(0x60)
    9316
                m4 := mload(0x80)
    9317
                m5 := mload(0xa0)
    9318
                m6 := mload(0xc0)
    9319
                m7 := mload(0xe0)
    9320
                m8 := mload(0x100)
    9321
                // Selector of `log(uint256,bool,string,string)`.
    9322
                mstore(0x00, 0x68c8b8bd)
    9323
                mstore(0x20, p0)
    9324
                mstore(0x40, p1)
    9325
                mstore(0x60, 0x80)
    9326
                mstore(0x80, 0xc0)
    9327
                writeString(0xa0, p2)
    9328
                writeString(0xe0, p3)
    9329
            }
    9330
            _sendLogPayload(0x1c, 0x104);
    9331
            /// @solidity memory-safe-assembly
    9332
            assembly {
    9333
                mstore(0x00, m0)
    9334
                mstore(0x20, m1)
    9335
                mstore(0x40, m2)
    9336
                mstore(0x60, m3)
    9337
                mstore(0x80, m4)
    9338
                mstore(0xa0, m5)
    9339
                mstore(0xc0, m6)
    9340
                mstore(0xe0, m7)
    9341
                mstore(0x100, m8)
    9342
            }
    9343
        }
    9344
    9345
        function log(uint256 p0, uint256 p1, address p2, address p3) internal pure {
    9346
            bytes32 m0;
    9347
            bytes32 m1;
    9348
            bytes32 m2;
    9349
            bytes32 m3;
    9350
            bytes32 m4;
    9351
            /// @solidity memory-safe-assembly
    9352
            assembly {
    9353
                m0 := mload(0x00)
    9354
                m1 := mload(0x20)
    9355
                m2 := mload(0x40)
    9356
                m3 := mload(0x60)
    9357
                m4 := mload(0x80)
    9358
                // Selector of `log(uint256,uint256,address,address)`.
    9359
                mstore(0x00, 0x56a5d1b1)
    9360
                mstore(0x20, p0)
    9361
                mstore(0x40, p1)
    9362
                mstore(0x60, p2)
    9363
                mstore(0x80, p3)
    9364
            }
    9365
            _sendLogPayload(0x1c, 0x84);
    9366
            /// @solidity memory-safe-assembly
    9367
            assembly {
    9368
                mstore(0x00, m0)
    9369
                mstore(0x20, m1)
    9370
                mstore(0x40, m2)
    9371
                mstore(0x60, m3)
    9372
                mstore(0x80, m4)
    9373
            }
    9374
        }
    9375
    9376
        function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure {
    9377
            bytes32 m0;
    9378
            bytes32 m1;
    9379
            bytes32 m2;
    9380
            bytes32 m3;
    9381
            bytes32 m4;
    9382
            /// @solidity memory-safe-assembly
    9383
            assembly {
    9384
                m0 := mload(0x00)
    9385
                m1 := mload(0x20)
    9386
                m2 := mload(0x40)
    9387
                m3 := mload(0x60)
    9388
                m4 := mload(0x80)
    9389
                // Selector of `log(uint256,uint256,address,bool)`.
    9390
                mstore(0x00, 0x15cac476)
    9391
                mstore(0x20, p0)
    9392
                mstore(0x40, p1)
    9393
                mstore(0x60, p2)
    9394
                mstore(0x80, p3)
    9395
            }
    9396
            _sendLogPayload(0x1c, 0x84);
    9397
            /// @solidity memory-safe-assembly
    9398
            assembly {
    9399
                mstore(0x00, m0)
    9400
                mstore(0x20, m1)
    9401
                mstore(0x40, m2)
    9402
                mstore(0x60, m3)
    9403
                mstore(0x80, m4)
    9404
            }
    9405
        }
    9406
    9407
        function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure {
    9408
            bytes32 m0;
    9409
            bytes32 m1;
    9410
            bytes32 m2;
    9411
            bytes32 m3;
    9412
            bytes32 m4;
    9413
            /// @solidity memory-safe-assembly
    9414
            assembly {
    9415
                m0 := mload(0x00)
    9416
                m1 := mload(0x20)
    9417
                m2 := mload(0x40)
    9418
                m3 := mload(0x60)
    9419
                m4 := mload(0x80)
    9420
                // Selector of `log(uint256,uint256,address,uint256)`.
    9421
                mstore(0x00, 0x88f6e4b2)
    9422
                mstore(0x20, p0)
    9423
                mstore(0x40, p1)
    9424
                mstore(0x60, p2)
    9425
                mstore(0x80, p3)
    9426
            }
    9427
            _sendLogPayload(0x1c, 0x84);
    9428
            /// @solidity memory-safe-assembly
    9429
            assembly {
    9430
                mstore(0x00, m0)
    9431
                mstore(0x20, m1)
    9432
                mstore(0x40, m2)
    9433
                mstore(0x60, m3)
    9434
                mstore(0x80, m4)
    9435
            }
    9436
        }
    9437
    9438
        function log(uint256 p0, uint256 p1, address p2, bytes32 p3) internal pure {
    9439
            bytes32 m0;
    9440
            bytes32 m1;
    9441
            bytes32 m2;
    9442
            bytes32 m3;
    9443
            bytes32 m4;
    9444
            bytes32 m5;
    9445
            bytes32 m6;
    9446
            /// @solidity memory-safe-assembly
    9447
            assembly {
    9448
                function writeString(pos, w) {
    9449
                    let length := 0
    9450
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    9451
                    mstore(pos, length)
    9452
                    let shift := sub(256, shl(3, length))
    9453
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    9454
                }
    9455
                m0 := mload(0x00)
    9456
                m1 := mload(0x20)
    9457
                m2 := mload(0x40)
    9458
                m3 := mload(0x60)
    9459
                m4 := mload(0x80)
    9460
                m5 := mload(0xa0)
    9461
                m6 := mload(0xc0)
    9462
                // Selector of `log(uint256,uint256,address,string)`.
    9463
                mstore(0x00, 0x6cde40b8)
    9464
                mstore(0x20, p0)
    9465
                mstore(0x40, p1)
    9466
                mstore(0x60, p2)
    9467
                mstore(0x80, 0x80)
    9468
                writeString(0xa0, p3)
    9469
            }
    9470
            _sendLogPayload(0x1c, 0xc4);
    9471
            /// @solidity memory-safe-assembly
    9472
            assembly {
    9473
                mstore(0x00, m0)
    9474
                mstore(0x20, m1)
    9475
                mstore(0x40, m2)
    9476
                mstore(0x60, m3)
    9477
                mstore(0x80, m4)
    9478
                mstore(0xa0, m5)
    9479
                mstore(0xc0, m6)
    9480
            }
    9481
        }
    9482
    9483
        function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure {
    9484
            bytes32 m0;
    9485
            bytes32 m1;
    9486
            bytes32 m2;
    9487
            bytes32 m3;
    9488
            bytes32 m4;
    9489
            /// @solidity memory-safe-assembly
    9490
            assembly {
    9491
                m0 := mload(0x00)
    9492
                m1 := mload(0x20)
    9493
                m2 := mload(0x40)
    9494
                m3 := mload(0x60)
    9495
                m4 := mload(0x80)
    9496
                // Selector of `log(uint256,uint256,bool,address)`.
    9497
                mstore(0x00, 0x9a816a83)
    9498
                mstore(0x20, p0)
    9499
                mstore(0x40, p1)
    9500
                mstore(0x60, p2)
    9501
                mstore(0x80, p3)
    9502
            }
    9503
            _sendLogPayload(0x1c, 0x84);
    9504
            /// @solidity memory-safe-assembly
    9505
            assembly {
    9506
                mstore(0x00, m0)
    9507
                mstore(0x20, m1)
    9508
                mstore(0x40, m2)
    9509
                mstore(0x60, m3)
    9510
                mstore(0x80, m4)
    9511
            }
    9512
        }
    9513
    9514
        function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure {
    9515
            bytes32 m0;
    9516
            bytes32 m1;
    9517
            bytes32 m2;
    9518
            bytes32 m3;
    9519
            bytes32 m4;
    9520
            /// @solidity memory-safe-assembly
    9521
            assembly {
    9522
                m0 := mload(0x00)
    9523
                m1 := mload(0x20)
    9524
                m2 := mload(0x40)
    9525
                m3 := mload(0x60)
    9526
                m4 := mload(0x80)
    9527
                // Selector of `log(uint256,uint256,bool,bool)`.
    9528
                mstore(0x00, 0xab085ae6)
    9529
                mstore(0x20, p0)
    9530
                mstore(0x40, p1)
    9531
                mstore(0x60, p2)
    9532
                mstore(0x80, p3)
    9533
            }
    9534
            _sendLogPayload(0x1c, 0x84);
    9535
            /// @solidity memory-safe-assembly
    9536
            assembly {
    9537
                mstore(0x00, m0)
    9538
                mstore(0x20, m1)
    9539
                mstore(0x40, m2)
    9540
                mstore(0x60, m3)
    9541
                mstore(0x80, m4)
    9542
            }
    9543
        }
    9544
    9545
        function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure {
    9546
            bytes32 m0;
    9547
            bytes32 m1;
    9548
            bytes32 m2;
    9549
            bytes32 m3;
    9550
            bytes32 m4;
    9551
            /// @solidity memory-safe-assembly
    9552
            assembly {
    9553
                m0 := mload(0x00)
    9554
                m1 := mload(0x20)
    9555
                m2 := mload(0x40)
    9556
                m3 := mload(0x60)
    9557
                m4 := mload(0x80)
    9558
                // Selector of `log(uint256,uint256,bool,uint256)`.
    9559
                mstore(0x00, 0xeb7f6fd2)
    9560
                mstore(0x20, p0)
    9561
                mstore(0x40, p1)
    9562
                mstore(0x60, p2)
    9563
                mstore(0x80, p3)
    9564
            }
    9565
            _sendLogPayload(0x1c, 0x84);
    9566
            /// @solidity memory-safe-assembly
    9567
            assembly {
    9568
                mstore(0x00, m0)
    9569
                mstore(0x20, m1)
    9570
                mstore(0x40, m2)
    9571
                mstore(0x60, m3)
    9572
                mstore(0x80, m4)
    9573
            }
    9574
        }
    9575
    9576
        function log(uint256 p0, uint256 p1, bool p2, bytes32 p3) internal pure {
    9577
            bytes32 m0;
    9578
            bytes32 m1;
    9579
            bytes32 m2;
    9580
            bytes32 m3;
    9581
            bytes32 m4;
    9582
            bytes32 m5;
    9583
            bytes32 m6;
    9584
            /// @solidity memory-safe-assembly
    9585
            assembly {
    9586
                function writeString(pos, w) {
    9587
                    let length := 0
    9588
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    9589
                    mstore(pos, length)
    9590
                    let shift := sub(256, shl(3, length))
    9591
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    9592
                }
    9593
                m0 := mload(0x00)
    9594
                m1 := mload(0x20)
    9595
                m2 := mload(0x40)
    9596
                m3 := mload(0x60)
    9597
                m4 := mload(0x80)
    9598
                m5 := mload(0xa0)
    9599
                m6 := mload(0xc0)
    9600
                // Selector of `log(uint256,uint256,bool,string)`.
    9601
                mstore(0x00, 0xa5b4fc99)
    9602
                mstore(0x20, p0)
    9603
                mstore(0x40, p1)
    9604
                mstore(0x60, p2)
    9605
                mstore(0x80, 0x80)
    9606
                writeString(0xa0, p3)
    9607
            }
    9608
            _sendLogPayload(0x1c, 0xc4);
    9609
            /// @solidity memory-safe-assembly
    9610
            assembly {
    9611
                mstore(0x00, m0)
    9612
                mstore(0x20, m1)
    9613
                mstore(0x40, m2)
    9614
                mstore(0x60, m3)
    9615
                mstore(0x80, m4)
    9616
                mstore(0xa0, m5)
    9617
                mstore(0xc0, m6)
    9618
            }
    9619
        }
    9620
    9621
        function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure {
    9622
            bytes32 m0;
    9623
            bytes32 m1;
    9624
            bytes32 m2;
    9625
            bytes32 m3;
    9626
            bytes32 m4;
    9627
            /// @solidity memory-safe-assembly
    9628
            assembly {
    9629
                m0 := mload(0x00)
    9630
                m1 := mload(0x20)
    9631
                m2 := mload(0x40)
    9632
                m3 := mload(0x60)
    9633
                m4 := mload(0x80)
    9634
                // Selector of `log(uint256,uint256,uint256,address)`.
    9635
                mstore(0x00, 0xfa8185af)
    9636
                mstore(0x20, p0)
    9637
                mstore(0x40, p1)
    9638
                mstore(0x60, p2)
    9639
                mstore(0x80, p3)
    9640
            }
    9641
            _sendLogPayload(0x1c, 0x84);
    9642
            /// @solidity memory-safe-assembly
    9643
            assembly {
    9644
                mstore(0x00, m0)
    9645
                mstore(0x20, m1)
    9646
                mstore(0x40, m2)
    9647
                mstore(0x60, m3)
    9648
                mstore(0x80, m4)
    9649
            }
    9650
        }
    9651
    9652
        function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure {
    9653
            bytes32 m0;
    9654
            bytes32 m1;
    9655
            bytes32 m2;
    9656
            bytes32 m3;
    9657
            bytes32 m4;
    9658
            /// @solidity memory-safe-assembly
    9659
            assembly {
    9660
                m0 := mload(0x00)
    9661
                m1 := mload(0x20)
    9662
                m2 := mload(0x40)
    9663
                m3 := mload(0x60)
    9664
                m4 := mload(0x80)
    9665
                // Selector of `log(uint256,uint256,uint256,bool)`.
    9666
                mstore(0x00, 0xc598d185)
    9667
                mstore(0x20, p0)
    9668
                mstore(0x40, p1)
    9669
                mstore(0x60, p2)
    9670
                mstore(0x80, p3)
    9671
            }
    9672
            _sendLogPayload(0x1c, 0x84);
    9673
            /// @solidity memory-safe-assembly
    9674
            assembly {
    9675
                mstore(0x00, m0)
    9676
                mstore(0x20, m1)
    9677
                mstore(0x40, m2)
    9678
                mstore(0x60, m3)
    9679
                mstore(0x80, m4)
    9680
            }
    9681
        }
    9682
    9683
        function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
    9684
            bytes32 m0;
    9685
            bytes32 m1;
    9686
            bytes32 m2;
    9687
            bytes32 m3;
    9688
            bytes32 m4;
    9689
            /// @solidity memory-safe-assembly
    9690
            assembly {
    9691
                m0 := mload(0x00)
    9692
                m1 := mload(0x20)
    9693
                m2 := mload(0x40)
    9694
                m3 := mload(0x60)
    9695
                m4 := mload(0x80)
    9696
                // Selector of `log(uint256,uint256,uint256,uint256)`.
    9697
                mstore(0x00, 0x193fb800)
    9698
                mstore(0x20, p0)
    9699
                mstore(0x40, p1)
    9700
                mstore(0x60, p2)
    9701
                mstore(0x80, p3)
    9702
            }
    9703
            _sendLogPayload(0x1c, 0x84);
    9704
            /// @solidity memory-safe-assembly
    9705
            assembly {
    9706
                mstore(0x00, m0)
    9707
                mstore(0x20, m1)
    9708
                mstore(0x40, m2)
    9709
                mstore(0x60, m3)
    9710
                mstore(0x80, m4)
    9711
            }
    9712
        }
    9713
    9714
        function log(uint256 p0, uint256 p1, uint256 p2, bytes32 p3) internal pure {
    9715
            bytes32 m0;
    9716
            bytes32 m1;
    9717
            bytes32 m2;
    9718
            bytes32 m3;
    9719
            bytes32 m4;
    9720
            bytes32 m5;
    9721
            bytes32 m6;
    9722
            /// @solidity memory-safe-assembly
    9723
            assembly {
    9724
                function writeString(pos, w) {
    9725
                    let length := 0
    9726
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    9727
                    mstore(pos, length)
    9728
                    let shift := sub(256, shl(3, length))
    9729
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    9730
                }
    9731
                m0 := mload(0x00)
    9732
                m1 := mload(0x20)
    9733
                m2 := mload(0x40)
    9734
                m3 := mload(0x60)
    9735
                m4 := mload(0x80)
    9736
                m5 := mload(0xa0)
    9737
                m6 := mload(0xc0)
    9738
                // Selector of `log(uint256,uint256,uint256,string)`.
    9739
                mstore(0x00, 0x59cfcbe3)
    9740
                mstore(0x20, p0)
    9741
                mstore(0x40, p1)
    9742
                mstore(0x60, p2)
    9743
                mstore(0x80, 0x80)
    9744
                writeString(0xa0, p3)
    9745
            }
    9746
            _sendLogPayload(0x1c, 0xc4);
    9747
            /// @solidity memory-safe-assembly
    9748
            assembly {
    9749
                mstore(0x00, m0)
    9750
                mstore(0x20, m1)
    9751
                mstore(0x40, m2)
    9752
                mstore(0x60, m3)
    9753
                mstore(0x80, m4)
    9754
                mstore(0xa0, m5)
    9755
                mstore(0xc0, m6)
    9756
            }
    9757
        }
    9758
    9759
        function log(uint256 p0, uint256 p1, bytes32 p2, address p3) internal pure {
    9760
            bytes32 m0;
    9761
            bytes32 m1;
    9762
            bytes32 m2;
    9763
            bytes32 m3;
    9764
            bytes32 m4;
    9765
            bytes32 m5;
    9766
            bytes32 m6;
    9767
            /// @solidity memory-safe-assembly
    9768
            assembly {
    9769
                function writeString(pos, w) {
    9770
                    let length := 0
    9771
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    9772
                    mstore(pos, length)
    9773
                    let shift := sub(256, shl(3, length))
    9774
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    9775
                }
    9776
                m0 := mload(0x00)
    9777
                m1 := mload(0x20)
    9778
                m2 := mload(0x40)
    9779
                m3 := mload(0x60)
    9780
                m4 := mload(0x80)
    9781
                m5 := mload(0xa0)
    9782
                m6 := mload(0xc0)
    9783
                // Selector of `log(uint256,uint256,string,address)`.
    9784
                mstore(0x00, 0x42d21db7)
    9785
                mstore(0x20, p0)
    9786
                mstore(0x40, p1)
    9787
                mstore(0x60, 0x80)
    9788
                mstore(0x80, p3)
    9789
                writeString(0xa0, p2)
    9790
            }
    9791
            _sendLogPayload(0x1c, 0xc4);
    9792
            /// @solidity memory-safe-assembly
    9793
            assembly {
    9794
                mstore(0x00, m0)
    9795
                mstore(0x20, m1)
    9796
                mstore(0x40, m2)
    9797
                mstore(0x60, m3)
    9798
                mstore(0x80, m4)
    9799
                mstore(0xa0, m5)
    9800
                mstore(0xc0, m6)
    9801
            }
    9802
        }
    9803
    9804
        function log(uint256 p0, uint256 p1, bytes32 p2, bool p3) internal pure {
    9805
            bytes32 m0;
    9806
            bytes32 m1;
    9807
            bytes32 m2;
    9808
            bytes32 m3;
    9809
            bytes32 m4;
    9810
            bytes32 m5;
    9811
            bytes32 m6;
    9812
            /// @solidity memory-safe-assembly
    9813
            assembly {
    9814
                function writeString(pos, w) {
    9815
                    let length := 0
    9816
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    9817
                    mstore(pos, length)
    9818
                    let shift := sub(256, shl(3, length))
    9819
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    9820
                }
    9821
                m0 := mload(0x00)
    9822
                m1 := mload(0x20)
    9823
                m2 := mload(0x40)
    9824
                m3 := mload(0x60)
    9825
                m4 := mload(0x80)
    9826
                m5 := mload(0xa0)
    9827
                m6 := mload(0xc0)
    9828
                // Selector of `log(uint256,uint256,string,bool)`.
    9829
                mstore(0x00, 0x7af6ab25)
    9830
                mstore(0x20, p0)
    9831
                mstore(0x40, p1)
    9832
                mstore(0x60, 0x80)
    9833
                mstore(0x80, p3)
    9834
                writeString(0xa0, p2)
    9835
            }
    9836
            _sendLogPayload(0x1c, 0xc4);
    9837
            /// @solidity memory-safe-assembly
    9838
            assembly {
    9839
                mstore(0x00, m0)
    9840
                mstore(0x20, m1)
    9841
                mstore(0x40, m2)
    9842
                mstore(0x60, m3)
    9843
                mstore(0x80, m4)
    9844
                mstore(0xa0, m5)
    9845
                mstore(0xc0, m6)
    9846
            }
    9847
        }
    9848
    9849
        function log(uint256 p0, uint256 p1, bytes32 p2, uint256 p3) internal pure {
    9850
            bytes32 m0;
    9851
            bytes32 m1;
    9852
            bytes32 m2;
    9853
            bytes32 m3;
    9854
            bytes32 m4;
    9855
            bytes32 m5;
    9856
            bytes32 m6;
    9857
            /// @solidity memory-safe-assembly
    9858
            assembly {
    9859
                function writeString(pos, w) {
    9860
                    let length := 0
    9861
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    9862
                    mstore(pos, length)
    9863
                    let shift := sub(256, shl(3, length))
    9864
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    9865
                }
    9866
                m0 := mload(0x00)
    9867
                m1 := mload(0x20)
    9868
                m2 := mload(0x40)
    9869
                m3 := mload(0x60)
    9870
                m4 := mload(0x80)
    9871
                m5 := mload(0xa0)
    9872
                m6 := mload(0xc0)
    9873
                // Selector of `log(uint256,uint256,string,uint256)`.
    9874
                mstore(0x00, 0x5da297eb)
    9875
                mstore(0x20, p0)
    9876
                mstore(0x40, p1)
    9877
                mstore(0x60, 0x80)
    9878
                mstore(0x80, p3)
    9879
                writeString(0xa0, p2)
    9880
            }
    9881
            _sendLogPayload(0x1c, 0xc4);
    9882
            /// @solidity memory-safe-assembly
    9883
            assembly {
    9884
                mstore(0x00, m0)
    9885
                mstore(0x20, m1)
    9886
                mstore(0x40, m2)
    9887
                mstore(0x60, m3)
    9888
                mstore(0x80, m4)
    9889
                mstore(0xa0, m5)
    9890
                mstore(0xc0, m6)
    9891
            }
    9892
        }
    9893
    9894
        function log(uint256 p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure {
    9895
            bytes32 m0;
    9896
            bytes32 m1;
    9897
            bytes32 m2;
    9898
            bytes32 m3;
    9899
            bytes32 m4;
    9900
            bytes32 m5;
    9901
            bytes32 m6;
    9902
            bytes32 m7;
    9903
            bytes32 m8;
    9904
            /// @solidity memory-safe-assembly
    9905
            assembly {
    9906
                function writeString(pos, w) {
    9907
                    let length := 0
    9908
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    9909
                    mstore(pos, length)
    9910
                    let shift := sub(256, shl(3, length))
    9911
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    9912
                }
    9913
                m0 := mload(0x00)
    9914
                m1 := mload(0x20)
    9915
                m2 := mload(0x40)
    9916
                m3 := mload(0x60)
    9917
                m4 := mload(0x80)
    9918
                m5 := mload(0xa0)
    9919
                m6 := mload(0xc0)
    9920
                m7 := mload(0xe0)
    9921
                m8 := mload(0x100)
    9922
                // Selector of `log(uint256,uint256,string,string)`.
    9923
                mstore(0x00, 0x27d8afd2)
    9924
                mstore(0x20, p0)
    9925
                mstore(0x40, p1)
    9926
                mstore(0x60, 0x80)
    9927
                mstore(0x80, 0xc0)
    9928
                writeString(0xa0, p2)
    9929
                writeString(0xe0, p3)
    9930
            }
    9931
            _sendLogPayload(0x1c, 0x104);
    9932
            /// @solidity memory-safe-assembly
    9933
            assembly {
    9934
                mstore(0x00, m0)
    9935
                mstore(0x20, m1)
    9936
                mstore(0x40, m2)
    9937
                mstore(0x60, m3)
    9938
                mstore(0x80, m4)
    9939
                mstore(0xa0, m5)
    9940
                mstore(0xc0, m6)
    9941
                mstore(0xe0, m7)
    9942
                mstore(0x100, m8)
    9943
            }
    9944
        }
    9945
    9946
        function log(uint256 p0, bytes32 p1, address p2, address p3) internal pure {
    9947
            bytes32 m0;
    9948
            bytes32 m1;
    9949
            bytes32 m2;
    9950
            bytes32 m3;
    9951
            bytes32 m4;
    9952
            bytes32 m5;
    9953
            bytes32 m6;
    9954
            /// @solidity memory-safe-assembly
    9955
            assembly {
    9956
                function writeString(pos, w) {
    9957
                    let length := 0
    9958
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    9959
                    mstore(pos, length)
    9960
                    let shift := sub(256, shl(3, length))
    9961
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    9962
                }
    9963
                m0 := mload(0x00)
    9964
                m1 := mload(0x20)
    9965
                m2 := mload(0x40)
    9966
                m3 := mload(0x60)
    9967
                m4 := mload(0x80)
    9968
                m5 := mload(0xa0)
    9969
                m6 := mload(0xc0)
    9970
                // Selector of `log(uint256,string,address,address)`.
    9971
                mstore(0x00, 0x6168ed61)
    9972
                mstore(0x20, p0)
    9973
                mstore(0x40, 0x80)
    9974
                mstore(0x60, p2)
    9975
                mstore(0x80, p3)
    9976
                writeString(0xa0, p1)
    9977
            }
    9978
            _sendLogPayload(0x1c, 0xc4);
    9979
            /// @solidity memory-safe-assembly
    9980
            assembly {
    9981
                mstore(0x00, m0)
    9982
                mstore(0x20, m1)
    9983
                mstore(0x40, m2)
    9984
                mstore(0x60, m3)
    9985
                mstore(0x80, m4)
    9986
                mstore(0xa0, m5)
    9987
                mstore(0xc0, m6)
    9988
            }
    9989
        }
    9990
    9991
        function log(uint256 p0, bytes32 p1, address p2, bool p3) internal pure {
    9992
            bytes32 m0;
    9993
            bytes32 m1;
    9994
            bytes32 m2;
    9995
            bytes32 m3;
    9996
            bytes32 m4;
    9997
            bytes32 m5;
    9998
            bytes32 m6;
    9999
            /// @solidity memory-safe-assembly
    10000
            assembly {
    10001
                function writeString(pos, w) {
    10002
                    let length := 0
    10003
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    10004
                    mstore(pos, length)
    10005
                    let shift := sub(256, shl(3, length))
    10006
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    10007
                }
    10008
                m0 := mload(0x00)
    10009
                m1 := mload(0x20)
    10010
                m2 := mload(0x40)
    10011
                m3 := mload(0x60)
    10012
                m4 := mload(0x80)
    10013
                m5 := mload(0xa0)
    10014
                m6 := mload(0xc0)
    10015
                // Selector of `log(uint256,string,address,bool)`.
    10016
                mstore(0x00, 0x90c30a56)
    10017
                mstore(0x20, p0)
    10018
                mstore(0x40, 0x80)
    10019
                mstore(0x60, p2)
    10020
                mstore(0x80, p3)
    10021
                writeString(0xa0, p1)
    10022
            }
    10023
            _sendLogPayload(0x1c, 0xc4);
    10024
            /// @solidity memory-safe-assembly
    10025
            assembly {
    10026
                mstore(0x00, m0)
    10027
                mstore(0x20, m1)
    10028
                mstore(0x40, m2)
    10029
                mstore(0x60, m3)
    10030
                mstore(0x80, m4)
    10031
                mstore(0xa0, m5)
    10032
                mstore(0xc0, m6)
    10033
            }
    10034
        }
    10035
    10036
        function log(uint256 p0, bytes32 p1, address p2, uint256 p3) internal pure {
    10037
            bytes32 m0;
    10038
            bytes32 m1;
    10039
            bytes32 m2;
    10040
            bytes32 m3;
    10041
            bytes32 m4;
    10042
            bytes32 m5;
    10043
            bytes32 m6;
    10044
            /// @solidity memory-safe-assembly
    10045
            assembly {
    10046
                function writeString(pos, w) {
    10047
                    let length := 0
    10048
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    10049
                    mstore(pos, length)
    10050
                    let shift := sub(256, shl(3, length))
    10051
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    10052
                }
    10053
                m0 := mload(0x00)
    10054
                m1 := mload(0x20)
    10055
                m2 := mload(0x40)
    10056
                m3 := mload(0x60)
    10057
                m4 := mload(0x80)
    10058
                m5 := mload(0xa0)
    10059
                m6 := mload(0xc0)
    10060
                // Selector of `log(uint256,string,address,uint256)`.
    10061
                mstore(0x00, 0xe8d3018d)
    10062
                mstore(0x20, p0)
    10063
                mstore(0x40, 0x80)
    10064
                mstore(0x60, p2)
    10065
                mstore(0x80, p3)
    10066
                writeString(0xa0, p1)
    10067
            }
    10068
            _sendLogPayload(0x1c, 0xc4);
    10069
            /// @solidity memory-safe-assembly
    10070
            assembly {
    10071
                mstore(0x00, m0)
    10072
                mstore(0x20, m1)
    10073
                mstore(0x40, m2)
    10074
                mstore(0x60, m3)
    10075
                mstore(0x80, m4)
    10076
                mstore(0xa0, m5)
    10077
                mstore(0xc0, m6)
    10078
            }
    10079
        }
    10080
    10081
        function log(uint256 p0, bytes32 p1, address p2, bytes32 p3) internal pure {
    10082
            bytes32 m0;
    10083
            bytes32 m1;
    10084
            bytes32 m2;
    10085
            bytes32 m3;
    10086
            bytes32 m4;
    10087
            bytes32 m5;
    10088
            bytes32 m6;
    10089
            bytes32 m7;
    10090
            bytes32 m8;
    10091
            /// @solidity memory-safe-assembly
    10092
            assembly {
    10093
                function writeString(pos, w) {
    10094
                    let length := 0
    10095
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    10096
                    mstore(pos, length)
    10097
                    let shift := sub(256, shl(3, length))
    10098
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    10099
                }
    10100
                m0 := mload(0x00)
    10101
                m1 := mload(0x20)
    10102
                m2 := mload(0x40)
    10103
                m3 := mload(0x60)
    10104
                m4 := mload(0x80)
    10105
                m5 := mload(0xa0)
    10106
                m6 := mload(0xc0)
    10107
                m7 := mload(0xe0)
    10108
                m8 := mload(0x100)
    10109
                // Selector of `log(uint256,string,address,string)`.
    10110
                mstore(0x00, 0x9c3adfa1)
    10111
                mstore(0x20, p0)
    10112
                mstore(0x40, 0x80)
    10113
                mstore(0x60, p2)
    10114
                mstore(0x80, 0xc0)
    10115
                writeString(0xa0, p1)
    10116
                writeString(0xe0, p3)
    10117
            }
    10118
            _sendLogPayload(0x1c, 0x104);
    10119
            /// @solidity memory-safe-assembly
    10120
            assembly {
    10121
                mstore(0x00, m0)
    10122
                mstore(0x20, m1)
    10123
                mstore(0x40, m2)
    10124
                mstore(0x60, m3)
    10125
                mstore(0x80, m4)
    10126
                mstore(0xa0, m5)
    10127
                mstore(0xc0, m6)
    10128
                mstore(0xe0, m7)
    10129
                mstore(0x100, m8)
    10130
            }
    10131
        }
    10132
    10133
        function log(uint256 p0, bytes32 p1, bool p2, address p3) internal pure {
    10134
            bytes32 m0;
    10135
            bytes32 m1;
    10136
            bytes32 m2;
    10137
            bytes32 m3;
    10138
            bytes32 m4;
    10139
            bytes32 m5;
    10140
            bytes32 m6;
    10141
            /// @solidity memory-safe-assembly
    10142
            assembly {
    10143
                function writeString(pos, w) {
    10144
                    let length := 0
    10145
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    10146
                    mstore(pos, length)
    10147
                    let shift := sub(256, shl(3, length))
    10148
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    10149
                }
    10150
                m0 := mload(0x00)
    10151
                m1 := mload(0x20)
    10152
                m2 := mload(0x40)
    10153
                m3 := mload(0x60)
    10154
                m4 := mload(0x80)
    10155
                m5 := mload(0xa0)
    10156
                m6 := mload(0xc0)
    10157
                // Selector of `log(uint256,string,bool,address)`.
    10158
                mstore(0x00, 0xae2ec581)
    10159
                mstore(0x20, p0)
    10160
                mstore(0x40, 0x80)
    10161
                mstore(0x60, p2)
    10162
                mstore(0x80, p3)
    10163
                writeString(0xa0, p1)
    10164
            }
    10165
            _sendLogPayload(0x1c, 0xc4);
    10166
            /// @solidity memory-safe-assembly
    10167
            assembly {
    10168
                mstore(0x00, m0)
    10169
                mstore(0x20, m1)
    10170
                mstore(0x40, m2)
    10171
                mstore(0x60, m3)
    10172
                mstore(0x80, m4)
    10173
                mstore(0xa0, m5)
    10174
                mstore(0xc0, m6)
    10175
            }
    10176
        }
    10177
    10178
        function log(uint256 p0, bytes32 p1, bool p2, bool p3) internal pure {
    10179
            bytes32 m0;
    10180
            bytes32 m1;
    10181
            bytes32 m2;
    10182
            bytes32 m3;
    10183
            bytes32 m4;
    10184
            bytes32 m5;
    10185
            bytes32 m6;
    10186
            /// @solidity memory-safe-assembly
    10187
            assembly {
    10188
                function writeString(pos, w) {
    10189
                    let length := 0
    10190
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    10191
                    mstore(pos, length)
    10192
                    let shift := sub(256, shl(3, length))
    10193
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    10194
                }
    10195
                m0 := mload(0x00)
    10196
                m1 := mload(0x20)
    10197
                m2 := mload(0x40)
    10198
                m3 := mload(0x60)
    10199
                m4 := mload(0x80)
    10200
                m5 := mload(0xa0)
    10201
                m6 := mload(0xc0)
    10202
                // Selector of `log(uint256,string,bool,bool)`.
    10203
                mstore(0x00, 0xba535d9c)
    10204
                mstore(0x20, p0)
    10205
                mstore(0x40, 0x80)
    10206
                mstore(0x60, p2)
    10207
                mstore(0x80, p3)
    10208
                writeString(0xa0, p1)
    10209
            }
    10210
            _sendLogPayload(0x1c, 0xc4);
    10211
            /// @solidity memory-safe-assembly
    10212
            assembly {
    10213
                mstore(0x00, m0)
    10214
                mstore(0x20, m1)
    10215
                mstore(0x40, m2)
    10216
                mstore(0x60, m3)
    10217
                mstore(0x80, m4)
    10218
                mstore(0xa0, m5)
    10219
                mstore(0xc0, m6)
    10220
            }
    10221
        }
    10222
    10223
        function log(uint256 p0, bytes32 p1, bool p2, uint256 p3) internal pure {
    10224
            bytes32 m0;
    10225
            bytes32 m1;
    10226
            bytes32 m2;
    10227
            bytes32 m3;
    10228
            bytes32 m4;
    10229
            bytes32 m5;
    10230
            bytes32 m6;
    10231
            /// @solidity memory-safe-assembly
    10232
            assembly {
    10233
                function writeString(pos, w) {
    10234
                    let length := 0
    10235
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    10236
                    mstore(pos, length)
    10237
                    let shift := sub(256, shl(3, length))
    10238
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    10239
                }
    10240
                m0 := mload(0x00)
    10241
                m1 := mload(0x20)
    10242
                m2 := mload(0x40)
    10243
                m3 := mload(0x60)
    10244
                m4 := mload(0x80)
    10245
                m5 := mload(0xa0)
    10246
                m6 := mload(0xc0)
    10247
                // Selector of `log(uint256,string,bool,uint256)`.
    10248
                mstore(0x00, 0xcf009880)
    10249
                mstore(0x20, p0)
    10250
                mstore(0x40, 0x80)
    10251
                mstore(0x60, p2)
    10252
                mstore(0x80, p3)
    10253
                writeString(0xa0, p1)
    10254
            }
    10255
            _sendLogPayload(0x1c, 0xc4);
    10256
            /// @solidity memory-safe-assembly
    10257
            assembly {
    10258
                mstore(0x00, m0)
    10259
                mstore(0x20, m1)
    10260
                mstore(0x40, m2)
    10261
                mstore(0x60, m3)
    10262
                mstore(0x80, m4)
    10263
                mstore(0xa0, m5)
    10264
                mstore(0xc0, m6)
    10265
            }
    10266
        }
    10267
    10268
        function log(uint256 p0, bytes32 p1, bool p2, bytes32 p3) internal pure {
    10269
            bytes32 m0;
    10270
            bytes32 m1;
    10271
            bytes32 m2;
    10272
            bytes32 m3;
    10273
            bytes32 m4;
    10274
            bytes32 m5;
    10275
            bytes32 m6;
    10276
            bytes32 m7;
    10277
            bytes32 m8;
    10278
            /// @solidity memory-safe-assembly
    10279
            assembly {
    10280
                function writeString(pos, w) {
    10281
                    let length := 0
    10282
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    10283
                    mstore(pos, length)
    10284
                    let shift := sub(256, shl(3, length))
    10285
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    10286
                }
    10287
                m0 := mload(0x00)
    10288
                m1 := mload(0x20)
    10289
                m2 := mload(0x40)
    10290
                m3 := mload(0x60)
    10291
                m4 := mload(0x80)
    10292
                m5 := mload(0xa0)
    10293
                m6 := mload(0xc0)
    10294
                m7 := mload(0xe0)
    10295
                m8 := mload(0x100)
    10296
                // Selector of `log(uint256,string,bool,string)`.
    10297
                mstore(0x00, 0xd2d423cd)
    10298
                mstore(0x20, p0)
    10299
                mstore(0x40, 0x80)
    10300
                mstore(0x60, p2)
    10301
                mstore(0x80, 0xc0)
    10302
                writeString(0xa0, p1)
    10303
                writeString(0xe0, p3)
    10304
            }
    10305
            _sendLogPayload(0x1c, 0x104);
    10306
            /// @solidity memory-safe-assembly
    10307
            assembly {
    10308
                mstore(0x00, m0)
    10309
                mstore(0x20, m1)
    10310
                mstore(0x40, m2)
    10311
                mstore(0x60, m3)
    10312
                mstore(0x80, m4)
    10313
                mstore(0xa0, m5)
    10314
                mstore(0xc0, m6)
    10315
                mstore(0xe0, m7)
    10316
                mstore(0x100, m8)
    10317
            }
    10318
        }
    10319
    10320
        function log(uint256 p0, bytes32 p1, uint256 p2, address p3) internal pure {
    10321
            bytes32 m0;
    10322
            bytes32 m1;
    10323
            bytes32 m2;
    10324
            bytes32 m3;
    10325
            bytes32 m4;
    10326
            bytes32 m5;
    10327
            bytes32 m6;
    10328
            /// @solidity memory-safe-assembly
    10329
            assembly {
    10330
                function writeString(pos, w) {
    10331
                    let length := 0
    10332
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    10333
                    mstore(pos, length)
    10334
                    let shift := sub(256, shl(3, length))
    10335
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    10336
                }
    10337
                m0 := mload(0x00)
    10338
                m1 := mload(0x20)
    10339
                m2 := mload(0x40)
    10340
                m3 := mload(0x60)
    10341
                m4 := mload(0x80)
    10342
                m5 := mload(0xa0)
    10343
                m6 := mload(0xc0)
    10344
                // Selector of `log(uint256,string,uint256,address)`.
    10345
                mstore(0x00, 0x3b2279b4)
    10346
                mstore(0x20, p0)
    10347
                mstore(0x40, 0x80)
    10348
                mstore(0x60, p2)
    10349
                mstore(0x80, p3)
    10350
                writeString(0xa0, p1)
    10351
            }
    10352
            _sendLogPayload(0x1c, 0xc4);
    10353
            /// @solidity memory-safe-assembly
    10354
            assembly {
    10355
                mstore(0x00, m0)
    10356
                mstore(0x20, m1)
    10357
                mstore(0x40, m2)
    10358
                mstore(0x60, m3)
    10359
                mstore(0x80, m4)
    10360
                mstore(0xa0, m5)
    10361
                mstore(0xc0, m6)
    10362
            }
    10363
        }
    10364
    10365
        function log(uint256 p0, bytes32 p1, uint256 p2, bool p3) internal pure {
    10366
            bytes32 m0;
    10367
            bytes32 m1;
    10368
            bytes32 m2;
    10369
            bytes32 m3;
    10370
            bytes32 m4;
    10371
            bytes32 m5;
    10372
            bytes32 m6;
    10373
            /// @solidity memory-safe-assembly
    10374
            assembly {
    10375
                function writeString(pos, w) {
    10376
                    let length := 0
    10377
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    10378
                    mstore(pos, length)
    10379
                    let shift := sub(256, shl(3, length))
    10380
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    10381
                }
    10382
                m0 := mload(0x00)
    10383
                m1 := mload(0x20)
    10384
                m2 := mload(0x40)
    10385
                m3 := mload(0x60)
    10386
                m4 := mload(0x80)
    10387
                m5 := mload(0xa0)
    10388
                m6 := mload(0xc0)
    10389
                // Selector of `log(uint256,string,uint256,bool)`.
    10390
                mstore(0x00, 0x691a8f74)
    10391
                mstore(0x20, p0)
    10392
                mstore(0x40, 0x80)
    10393
                mstore(0x60, p2)
    10394
                mstore(0x80, p3)
    10395
                writeString(0xa0, p1)
    10396
            }
    10397
            _sendLogPayload(0x1c, 0xc4);
    10398
            /// @solidity memory-safe-assembly
    10399
            assembly {
    10400
                mstore(0x00, m0)
    10401
                mstore(0x20, m1)
    10402
                mstore(0x40, m2)
    10403
                mstore(0x60, m3)
    10404
                mstore(0x80, m4)
    10405
                mstore(0xa0, m5)
    10406
                mstore(0xc0, m6)
    10407
            }
    10408
        }
    10409
    10410
        function log(uint256 p0, bytes32 p1, uint256 p2, uint256 p3) internal pure {
    10411
            bytes32 m0;
    10412
            bytes32 m1;
    10413
            bytes32 m2;
    10414
            bytes32 m3;
    10415
            bytes32 m4;
    10416
            bytes32 m5;
    10417
            bytes32 m6;
    10418
            /// @solidity memory-safe-assembly
    10419
            assembly {
    10420
                function writeString(pos, w) {
    10421
                    let length := 0
    10422
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    10423
                    mstore(pos, length)
    10424
                    let shift := sub(256, shl(3, length))
    10425
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    10426
                }
    10427
                m0 := mload(0x00)
    10428
                m1 := mload(0x20)
    10429
                m2 := mload(0x40)
    10430
                m3 := mload(0x60)
    10431
                m4 := mload(0x80)
    10432
                m5 := mload(0xa0)
    10433
                m6 := mload(0xc0)
    10434
                // Selector of `log(uint256,string,uint256,uint256)`.
    10435
                mstore(0x00, 0x82c25b74)
    10436
                mstore(0x20, p0)
    10437
                mstore(0x40, 0x80)
    10438
                mstore(0x60, p2)
    10439
                mstore(0x80, p3)
    10440
                writeString(0xa0, p1)
    10441
            }
    10442
            _sendLogPayload(0x1c, 0xc4);
    10443
            /// @solidity memory-safe-assembly
    10444
            assembly {
    10445
                mstore(0x00, m0)
    10446
                mstore(0x20, m1)
    10447
                mstore(0x40, m2)
    10448
                mstore(0x60, m3)
    10449
                mstore(0x80, m4)
    10450
                mstore(0xa0, m5)
    10451
                mstore(0xc0, m6)
    10452
            }
    10453
        }
    10454
    10455
        function log(uint256 p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure {
    10456
            bytes32 m0;
    10457
            bytes32 m1;
    10458
            bytes32 m2;
    10459
            bytes32 m3;
    10460
            bytes32 m4;
    10461
            bytes32 m5;
    10462
            bytes32 m6;
    10463
            bytes32 m7;
    10464
            bytes32 m8;
    10465
            /// @solidity memory-safe-assembly
    10466
            assembly {
    10467
                function writeString(pos, w) {
    10468
                    let length := 0
    10469
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    10470
                    mstore(pos, length)
    10471
                    let shift := sub(256, shl(3, length))
    10472
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    10473
                }
    10474
                m0 := mload(0x00)
    10475
                m1 := mload(0x20)
    10476
                m2 := mload(0x40)
    10477
                m3 := mload(0x60)
    10478
                m4 := mload(0x80)
    10479
                m5 := mload(0xa0)
    10480
                m6 := mload(0xc0)
    10481
                m7 := mload(0xe0)
    10482
                m8 := mload(0x100)
    10483
                // Selector of `log(uint256,string,uint256,string)`.
    10484
                mstore(0x00, 0xb7b914ca)
    10485
                mstore(0x20, p0)
    10486
                mstore(0x40, 0x80)
    10487
                mstore(0x60, p2)
    10488
                mstore(0x80, 0xc0)
    10489
                writeString(0xa0, p1)
    10490
                writeString(0xe0, p3)
    10491
            }
    10492
            _sendLogPayload(0x1c, 0x104);
    10493
            /// @solidity memory-safe-assembly
    10494
            assembly {
    10495
                mstore(0x00, m0)
    10496
                mstore(0x20, m1)
    10497
                mstore(0x40, m2)
    10498
                mstore(0x60, m3)
    10499
                mstore(0x80, m4)
    10500
                mstore(0xa0, m5)
    10501
                mstore(0xc0, m6)
    10502
                mstore(0xe0, m7)
    10503
                mstore(0x100, m8)
    10504
            }
    10505
        }
    10506
    10507
        function log(uint256 p0, bytes32 p1, bytes32 p2, address p3) internal pure {
    10508
            bytes32 m0;
    10509
            bytes32 m1;
    10510
            bytes32 m2;
    10511
            bytes32 m3;
    10512
            bytes32 m4;
    10513
            bytes32 m5;
    10514
            bytes32 m6;
    10515
            bytes32 m7;
    10516
            bytes32 m8;
    10517
            /// @solidity memory-safe-assembly
    10518
            assembly {
    10519
                function writeString(pos, w) {
    10520
                    let length := 0
    10521
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    10522
                    mstore(pos, length)
    10523
                    let shift := sub(256, shl(3, length))
    10524
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    10525
                }
    10526
                m0 := mload(0x00)
    10527
                m1 := mload(0x20)
    10528
                m2 := mload(0x40)
    10529
                m3 := mload(0x60)
    10530
                m4 := mload(0x80)
    10531
                m5 := mload(0xa0)
    10532
                m6 := mload(0xc0)
    10533
                m7 := mload(0xe0)
    10534
                m8 := mload(0x100)
    10535
                // Selector of `log(uint256,string,string,address)`.
    10536
                mstore(0x00, 0xd583c602)
    10537
                mstore(0x20, p0)
    10538
                mstore(0x40, 0x80)
    10539
                mstore(0x60, 0xc0)
    10540
                mstore(0x80, p3)
    10541
                writeString(0xa0, p1)
    10542
                writeString(0xe0, p2)
    10543
            }
    10544
            _sendLogPayload(0x1c, 0x104);
    10545
            /// @solidity memory-safe-assembly
    10546
            assembly {
    10547
                mstore(0x00, m0)
    10548
                mstore(0x20, m1)
    10549
                mstore(0x40, m2)
    10550
                mstore(0x60, m3)
    10551
                mstore(0x80, m4)
    10552
                mstore(0xa0, m5)
    10553
                mstore(0xc0, m6)
    10554
                mstore(0xe0, m7)
    10555
                mstore(0x100, m8)
    10556
            }
    10557
        }
    10558
    10559
        function log(uint256 p0, bytes32 p1, bytes32 p2, bool p3) internal pure {
    10560
            bytes32 m0;
    10561
            bytes32 m1;
    10562
            bytes32 m2;
    10563
            bytes32 m3;
    10564
            bytes32 m4;
    10565
            bytes32 m5;
    10566
            bytes32 m6;
    10567
            bytes32 m7;
    10568
            bytes32 m8;
    10569
            /// @solidity memory-safe-assembly
    10570
            assembly {
    10571
                function writeString(pos, w) {
    10572
                    let length := 0
    10573
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    10574
                    mstore(pos, length)
    10575
                    let shift := sub(256, shl(3, length))
    10576
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    10577
                }
    10578
                m0 := mload(0x00)
    10579
                m1 := mload(0x20)
    10580
                m2 := mload(0x40)
    10581
                m3 := mload(0x60)
    10582
                m4 := mload(0x80)
    10583
                m5 := mload(0xa0)
    10584
                m6 := mload(0xc0)
    10585
                m7 := mload(0xe0)
    10586
                m8 := mload(0x100)
    10587
                // Selector of `log(uint256,string,string,bool)`.
    10588
                mstore(0x00, 0xb3a6b6bd)
    10589
                mstore(0x20, p0)
    10590
                mstore(0x40, 0x80)
    10591
                mstore(0x60, 0xc0)
    10592
                mstore(0x80, p3)
    10593
                writeString(0xa0, p1)
    10594
                writeString(0xe0, p2)
    10595
            }
    10596
            _sendLogPayload(0x1c, 0x104);
    10597
            /// @solidity memory-safe-assembly
    10598
            assembly {
    10599
                mstore(0x00, m0)
    10600
                mstore(0x20, m1)
    10601
                mstore(0x40, m2)
    10602
                mstore(0x60, m3)
    10603
                mstore(0x80, m4)
    10604
                mstore(0xa0, m5)
    10605
                mstore(0xc0, m6)
    10606
                mstore(0xe0, m7)
    10607
                mstore(0x100, m8)
    10608
            }
    10609
        }
    10610
    10611
        function log(uint256 p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure {
    10612
            bytes32 m0;
    10613
            bytes32 m1;
    10614
            bytes32 m2;
    10615
            bytes32 m3;
    10616
            bytes32 m4;
    10617
            bytes32 m5;
    10618
            bytes32 m6;
    10619
            bytes32 m7;
    10620
            bytes32 m8;
    10621
            /// @solidity memory-safe-assembly
    10622
            assembly {
    10623
                function writeString(pos, w) {
    10624
                    let length := 0
    10625
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    10626
                    mstore(pos, length)
    10627
                    let shift := sub(256, shl(3, length))
    10628
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    10629
                }
    10630
                m0 := mload(0x00)
    10631
                m1 := mload(0x20)
    10632
                m2 := mload(0x40)
    10633
                m3 := mload(0x60)
    10634
                m4 := mload(0x80)
    10635
                m5 := mload(0xa0)
    10636
                m6 := mload(0xc0)
    10637
                m7 := mload(0xe0)
    10638
                m8 := mload(0x100)
    10639
                // Selector of `log(uint256,string,string,uint256)`.
    10640
                mstore(0x00, 0xb028c9bd)
    10641
                mstore(0x20, p0)
    10642
                mstore(0x40, 0x80)
    10643
                mstore(0x60, 0xc0)
    10644
                mstore(0x80, p3)
    10645
                writeString(0xa0, p1)
    10646
                writeString(0xe0, p2)
    10647
            }
    10648
            _sendLogPayload(0x1c, 0x104);
    10649
            /// @solidity memory-safe-assembly
    10650
            assembly {
    10651
                mstore(0x00, m0)
    10652
                mstore(0x20, m1)
    10653
                mstore(0x40, m2)
    10654
                mstore(0x60, m3)
    10655
                mstore(0x80, m4)
    10656
                mstore(0xa0, m5)
    10657
                mstore(0xc0, m6)
    10658
                mstore(0xe0, m7)
    10659
                mstore(0x100, m8)
    10660
            }
    10661
        }
    10662
    10663
        function log(uint256 p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure {
    10664
            bytes32 m0;
    10665
            bytes32 m1;
    10666
            bytes32 m2;
    10667
            bytes32 m3;
    10668
            bytes32 m4;
    10669
            bytes32 m5;
    10670
            bytes32 m6;
    10671
            bytes32 m7;
    10672
            bytes32 m8;
    10673
            bytes32 m9;
    10674
            bytes32 m10;
    10675
            /// @solidity memory-safe-assembly
    10676
            assembly {
    10677
                function writeString(pos, w) {
    10678
                    let length := 0
    10679
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    10680
                    mstore(pos, length)
    10681
                    let shift := sub(256, shl(3, length))
    10682
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    10683
                }
    10684
                m0 := mload(0x00)
    10685
                m1 := mload(0x20)
    10686
                m2 := mload(0x40)
    10687
                m3 := mload(0x60)
    10688
                m4 := mload(0x80)
    10689
                m5 := mload(0xa0)
    10690
                m6 := mload(0xc0)
    10691
                m7 := mload(0xe0)
    10692
                m8 := mload(0x100)
    10693
                m9 := mload(0x120)
    10694
                m10 := mload(0x140)
    10695
                // Selector of `log(uint256,string,string,string)`.
    10696
                mstore(0x00, 0x21ad0683)
    10697
                mstore(0x20, p0)
    10698
                mstore(0x40, 0x80)
    10699
                mstore(0x60, 0xc0)
    10700
                mstore(0x80, 0x100)
    10701
                writeString(0xa0, p1)
    10702
                writeString(0xe0, p2)
    10703
                writeString(0x120, p3)
    10704
            }
    10705
            _sendLogPayload(0x1c, 0x144);
    10706
            /// @solidity memory-safe-assembly
    10707
            assembly {
    10708
                mstore(0x00, m0)
    10709
                mstore(0x20, m1)
    10710
                mstore(0x40, m2)
    10711
                mstore(0x60, m3)
    10712
                mstore(0x80, m4)
    10713
                mstore(0xa0, m5)
    10714
                mstore(0xc0, m6)
    10715
                mstore(0xe0, m7)
    10716
                mstore(0x100, m8)
    10717
                mstore(0x120, m9)
    10718
                mstore(0x140, m10)
    10719
            }
    10720
        }
    10721
    10722
        function log(bytes32 p0, address p1, address p2, address p3) internal pure {
    10723
            bytes32 m0;
    10724
            bytes32 m1;
    10725
            bytes32 m2;
    10726
            bytes32 m3;
    10727
            bytes32 m4;
    10728
            bytes32 m5;
    10729
            bytes32 m6;
    10730
            /// @solidity memory-safe-assembly
    10731
            assembly {
    10732
                function writeString(pos, w) {
    10733
                    let length := 0
    10734
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    10735
                    mstore(pos, length)
    10736
                    let shift := sub(256, shl(3, length))
    10737
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    10738
                }
    10739
                m0 := mload(0x00)
    10740
                m1 := mload(0x20)
    10741
                m2 := mload(0x40)
    10742
                m3 := mload(0x60)
    10743
                m4 := mload(0x80)
    10744
                m5 := mload(0xa0)
    10745
                m6 := mload(0xc0)
    10746
                // Selector of `log(string,address,address,address)`.
    10747
                mstore(0x00, 0xed8f28f6)
    10748
                mstore(0x20, 0x80)
    10749
                mstore(0x40, p1)
    10750
                mstore(0x60, p2)
    10751
                mstore(0x80, p3)
    10752
                writeString(0xa0, p0)
    10753
            }
    10754
            _sendLogPayload(0x1c, 0xc4);
    10755
            /// @solidity memory-safe-assembly
    10756
            assembly {
    10757
                mstore(0x00, m0)
    10758
                mstore(0x20, m1)
    10759
                mstore(0x40, m2)
    10760
                mstore(0x60, m3)
    10761
                mstore(0x80, m4)
    10762
                mstore(0xa0, m5)
    10763
                mstore(0xc0, m6)
    10764
            }
    10765
        }
    10766
    10767
        function log(bytes32 p0, address p1, address p2, bool p3) internal pure {
    10768
            bytes32 m0;
    10769
            bytes32 m1;
    10770
            bytes32 m2;
    10771
            bytes32 m3;
    10772
            bytes32 m4;
    10773
            bytes32 m5;
    10774
            bytes32 m6;
    10775
            /// @solidity memory-safe-assembly
    10776
            assembly {
    10777
                function writeString(pos, w) {
    10778
                    let length := 0
    10779
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    10780
                    mstore(pos, length)
    10781
                    let shift := sub(256, shl(3, length))
    10782
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    10783
                }
    10784
                m0 := mload(0x00)
    10785
                m1 := mload(0x20)
    10786
                m2 := mload(0x40)
    10787
                m3 := mload(0x60)
    10788
                m4 := mload(0x80)
    10789
                m5 := mload(0xa0)
    10790
                m6 := mload(0xc0)
    10791
                // Selector of `log(string,address,address,bool)`.
    10792
                mstore(0x00, 0xb59dbd60)
    10793
                mstore(0x20, 0x80)
    10794
                mstore(0x40, p1)
    10795
                mstore(0x60, p2)
    10796
                mstore(0x80, p3)
    10797
                writeString(0xa0, p0)
    10798
            }
    10799
            _sendLogPayload(0x1c, 0xc4);
    10800
            /// @solidity memory-safe-assembly
    10801
            assembly {
    10802
                mstore(0x00, m0)
    10803
                mstore(0x20, m1)
    10804
                mstore(0x40, m2)
    10805
                mstore(0x60, m3)
    10806
                mstore(0x80, m4)
    10807
                mstore(0xa0, m5)
    10808
                mstore(0xc0, m6)
    10809
            }
    10810
        }
    10811
    10812
        function log(bytes32 p0, address p1, address p2, uint256 p3) internal pure {
    10813
            bytes32 m0;
    10814
            bytes32 m1;
    10815
            bytes32 m2;
    10816
            bytes32 m3;
    10817
            bytes32 m4;
    10818
            bytes32 m5;
    10819
            bytes32 m6;
    10820
            /// @solidity memory-safe-assembly
    10821
            assembly {
    10822
                function writeString(pos, w) {
    10823
                    let length := 0
    10824
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    10825
                    mstore(pos, length)
    10826
                    let shift := sub(256, shl(3, length))
    10827
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    10828
                }
    10829
                m0 := mload(0x00)
    10830
                m1 := mload(0x20)
    10831
                m2 := mload(0x40)
    10832
                m3 := mload(0x60)
    10833
                m4 := mload(0x80)
    10834
                m5 := mload(0xa0)
    10835
                m6 := mload(0xc0)
    10836
                // Selector of `log(string,address,address,uint256)`.
    10837
                mstore(0x00, 0x8ef3f399)
    10838
                mstore(0x20, 0x80)
    10839
                mstore(0x40, p1)
    10840
                mstore(0x60, p2)
    10841
                mstore(0x80, p3)
    10842
                writeString(0xa0, p0)
    10843
            }
    10844
            _sendLogPayload(0x1c, 0xc4);
    10845
            /// @solidity memory-safe-assembly
    10846
            assembly {
    10847
                mstore(0x00, m0)
    10848
                mstore(0x20, m1)
    10849
                mstore(0x40, m2)
    10850
                mstore(0x60, m3)
    10851
                mstore(0x80, m4)
    10852
                mstore(0xa0, m5)
    10853
                mstore(0xc0, m6)
    10854
            }
    10855
        }
    10856
    10857
        function log(bytes32 p0, address p1, address p2, bytes32 p3) internal pure {
    10858
            bytes32 m0;
    10859
            bytes32 m1;
    10860
            bytes32 m2;
    10861
            bytes32 m3;
    10862
            bytes32 m4;
    10863
            bytes32 m5;
    10864
            bytes32 m6;
    10865
            bytes32 m7;
    10866
            bytes32 m8;
    10867
            /// @solidity memory-safe-assembly
    10868
            assembly {
    10869
                function writeString(pos, w) {
    10870
                    let length := 0
    10871
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    10872
                    mstore(pos, length)
    10873
                    let shift := sub(256, shl(3, length))
    10874
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    10875
                }
    10876
                m0 := mload(0x00)
    10877
                m1 := mload(0x20)
    10878
                m2 := mload(0x40)
    10879
                m3 := mload(0x60)
    10880
                m4 := mload(0x80)
    10881
                m5 := mload(0xa0)
    10882
                m6 := mload(0xc0)
    10883
                m7 := mload(0xe0)
    10884
                m8 := mload(0x100)
    10885
                // Selector of `log(string,address,address,string)`.
    10886
                mstore(0x00, 0x800a1c67)
    10887
                mstore(0x20, 0x80)
    10888
                mstore(0x40, p1)
    10889
                mstore(0x60, p2)
    10890
                mstore(0x80, 0xc0)
    10891
                writeString(0xa0, p0)
    10892
                writeString(0xe0, p3)
    10893
            }
    10894
            _sendLogPayload(0x1c, 0x104);
    10895
            /// @solidity memory-safe-assembly
    10896
            assembly {
    10897
                mstore(0x00, m0)
    10898
                mstore(0x20, m1)
    10899
                mstore(0x40, m2)
    10900
                mstore(0x60, m3)
    10901
                mstore(0x80, m4)
    10902
                mstore(0xa0, m5)
    10903
                mstore(0xc0, m6)
    10904
                mstore(0xe0, m7)
    10905
                mstore(0x100, m8)
    10906
            }
    10907
        }
    10908
    10909
        function log(bytes32 p0, address p1, bool p2, address p3) internal pure {
    10910
            bytes32 m0;
    10911
            bytes32 m1;
    10912
            bytes32 m2;
    10913
            bytes32 m3;
    10914
            bytes32 m4;
    10915
            bytes32 m5;
    10916
            bytes32 m6;
    10917
            /// @solidity memory-safe-assembly
    10918
            assembly {
    10919
                function writeString(pos, w) {
    10920
                    let length := 0
    10921
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    10922
                    mstore(pos, length)
    10923
                    let shift := sub(256, shl(3, length))
    10924
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    10925
                }
    10926
                m0 := mload(0x00)
    10927
                m1 := mload(0x20)
    10928
                m2 := mload(0x40)
    10929
                m3 := mload(0x60)
    10930
                m4 := mload(0x80)
    10931
                m5 := mload(0xa0)
    10932
                m6 := mload(0xc0)
    10933
                // Selector of `log(string,address,bool,address)`.
    10934
                mstore(0x00, 0x223603bd)
    10935
                mstore(0x20, 0x80)
    10936
                mstore(0x40, p1)
    10937
                mstore(0x60, p2)
    10938
                mstore(0x80, p3)
    10939
                writeString(0xa0, p0)
    10940
            }
    10941
            _sendLogPayload(0x1c, 0xc4);
    10942
            /// @solidity memory-safe-assembly
    10943
            assembly {
    10944
                mstore(0x00, m0)
    10945
                mstore(0x20, m1)
    10946
                mstore(0x40, m2)
    10947
                mstore(0x60, m3)
    10948
                mstore(0x80, m4)
    10949
                mstore(0xa0, m5)
    10950
                mstore(0xc0, m6)
    10951
            }
    10952
        }
    10953
    10954
        function log(bytes32 p0, address p1, bool p2, bool p3) internal pure {
    10955
            bytes32 m0;
    10956
            bytes32 m1;
    10957
            bytes32 m2;
    10958
            bytes32 m3;
    10959
            bytes32 m4;
    10960
            bytes32 m5;
    10961
            bytes32 m6;
    10962
            /// @solidity memory-safe-assembly
    10963
            assembly {
    10964
                function writeString(pos, w) {
    10965
                    let length := 0
    10966
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    10967
                    mstore(pos, length)
    10968
                    let shift := sub(256, shl(3, length))
    10969
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    10970
                }
    10971
                m0 := mload(0x00)
    10972
                m1 := mload(0x20)
    10973
                m2 := mload(0x40)
    10974
                m3 := mload(0x60)
    10975
                m4 := mload(0x80)
    10976
                m5 := mload(0xa0)
    10977
                m6 := mload(0xc0)
    10978
                // Selector of `log(string,address,bool,bool)`.
    10979
                mstore(0x00, 0x79884c2b)
    10980
                mstore(0x20, 0x80)
    10981
                mstore(0x40, p1)
    10982
                mstore(0x60, p2)
    10983
                mstore(0x80, p3)
    10984
                writeString(0xa0, p0)
    10985
            }
    10986
            _sendLogPayload(0x1c, 0xc4);
    10987
            /// @solidity memory-safe-assembly
    10988
            assembly {
    10989
                mstore(0x00, m0)
    10990
                mstore(0x20, m1)
    10991
                mstore(0x40, m2)
    10992
                mstore(0x60, m3)
    10993
                mstore(0x80, m4)
    10994
                mstore(0xa0, m5)
    10995
                mstore(0xc0, m6)
    10996
            }
    10997
        }
    10998
    10999
        function log(bytes32 p0, address p1, bool p2, uint256 p3) internal pure {
    11000
            bytes32 m0;
    11001
            bytes32 m1;
    11002
            bytes32 m2;
    11003
            bytes32 m3;
    11004
            bytes32 m4;
    11005
            bytes32 m5;
    11006
            bytes32 m6;
    11007
            /// @solidity memory-safe-assembly
    11008
            assembly {
    11009
                function writeString(pos, w) {
    11010
                    let length := 0
    11011
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    11012
                    mstore(pos, length)
    11013
                    let shift := sub(256, shl(3, length))
    11014
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    11015
                }
    11016
                m0 := mload(0x00)
    11017
                m1 := mload(0x20)
    11018
                m2 := mload(0x40)
    11019
                m3 := mload(0x60)
    11020
                m4 := mload(0x80)
    11021
                m5 := mload(0xa0)
    11022
                m6 := mload(0xc0)
    11023
                // Selector of `log(string,address,bool,uint256)`.
    11024
                mstore(0x00, 0x3e9f866a)
    11025
                mstore(0x20, 0x80)
    11026
                mstore(0x40, p1)
    11027
                mstore(0x60, p2)
    11028
                mstore(0x80, p3)
    11029
                writeString(0xa0, p0)
    11030
            }
    11031
            _sendLogPayload(0x1c, 0xc4);
    11032
            /// @solidity memory-safe-assembly
    11033
            assembly {
    11034
                mstore(0x00, m0)
    11035
                mstore(0x20, m1)
    11036
                mstore(0x40, m2)
    11037
                mstore(0x60, m3)
    11038
                mstore(0x80, m4)
    11039
                mstore(0xa0, m5)
    11040
                mstore(0xc0, m6)
    11041
            }
    11042
        }
    11043
    11044
        function log(bytes32 p0, address p1, bool p2, bytes32 p3) internal pure {
    11045
            bytes32 m0;
    11046
            bytes32 m1;
    11047
            bytes32 m2;
    11048
            bytes32 m3;
    11049
            bytes32 m4;
    11050
            bytes32 m5;
    11051
            bytes32 m6;
    11052
            bytes32 m7;
    11053
            bytes32 m8;
    11054
            /// @solidity memory-safe-assembly
    11055
            assembly {
    11056
                function writeString(pos, w) {
    11057
                    let length := 0
    11058
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    11059
                    mstore(pos, length)
    11060
                    let shift := sub(256, shl(3, length))
    11061
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    11062
                }
    11063
                m0 := mload(0x00)
    11064
                m1 := mload(0x20)
    11065
                m2 := mload(0x40)
    11066
                m3 := mload(0x60)
    11067
                m4 := mload(0x80)
    11068
                m5 := mload(0xa0)
    11069
                m6 := mload(0xc0)
    11070
                m7 := mload(0xe0)
    11071
                m8 := mload(0x100)
    11072
                // Selector of `log(string,address,bool,string)`.
    11073
                mstore(0x00, 0x0454c079)
    11074
                mstore(0x20, 0x80)
    11075
                mstore(0x40, p1)
    11076
                mstore(0x60, p2)
    11077
                mstore(0x80, 0xc0)
    11078
                writeString(0xa0, p0)
    11079
                writeString(0xe0, p3)
    11080
            }
    11081
            _sendLogPayload(0x1c, 0x104);
    11082
            /// @solidity memory-safe-assembly
    11083
            assembly {
    11084
                mstore(0x00, m0)
    11085
                mstore(0x20, m1)
    11086
                mstore(0x40, m2)
    11087
                mstore(0x60, m3)
    11088
                mstore(0x80, m4)
    11089
                mstore(0xa0, m5)
    11090
                mstore(0xc0, m6)
    11091
                mstore(0xe0, m7)
    11092
                mstore(0x100, m8)
    11093
            }
    11094
        }
    11095
    11096
        function log(bytes32 p0, address p1, uint256 p2, address p3) internal pure {
    11097
            bytes32 m0;
    11098
            bytes32 m1;
    11099
            bytes32 m2;
    11100
            bytes32 m3;
    11101
            bytes32 m4;
    11102
            bytes32 m5;
    11103
            bytes32 m6;
    11104
            /// @solidity memory-safe-assembly
    11105
            assembly {
    11106
                function writeString(pos, w) {
    11107
                    let length := 0
    11108
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    11109
                    mstore(pos, length)
    11110
                    let shift := sub(256, shl(3, length))
    11111
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    11112
                }
    11113
                m0 := mload(0x00)
    11114
                m1 := mload(0x20)
    11115
                m2 := mload(0x40)
    11116
                m3 := mload(0x60)
    11117
                m4 := mload(0x80)
    11118
                m5 := mload(0xa0)
    11119
                m6 := mload(0xc0)
    11120
                // Selector of `log(string,address,uint256,address)`.
    11121
                mstore(0x00, 0x63fb8bc5)
    11122
                mstore(0x20, 0x80)
    11123
                mstore(0x40, p1)
    11124
                mstore(0x60, p2)
    11125
                mstore(0x80, p3)
    11126
                writeString(0xa0, p0)
    11127
            }
    11128
            _sendLogPayload(0x1c, 0xc4);
    11129
            /// @solidity memory-safe-assembly
    11130
            assembly {
    11131
                mstore(0x00, m0)
    11132
                mstore(0x20, m1)
    11133
                mstore(0x40, m2)
    11134
                mstore(0x60, m3)
    11135
                mstore(0x80, m4)
    11136
                mstore(0xa0, m5)
    11137
                mstore(0xc0, m6)
    11138
            }
    11139
        }
    11140
    11141
        function log(bytes32 p0, address p1, uint256 p2, bool p3) internal pure {
    11142
            bytes32 m0;
    11143
            bytes32 m1;
    11144
            bytes32 m2;
    11145
            bytes32 m3;
    11146
            bytes32 m4;
    11147
            bytes32 m5;
    11148
            bytes32 m6;
    11149
            /// @solidity memory-safe-assembly
    11150
            assembly {
    11151
                function writeString(pos, w) {
    11152
                    let length := 0
    11153
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    11154
                    mstore(pos, length)
    11155
                    let shift := sub(256, shl(3, length))
    11156
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    11157
                }
    11158
                m0 := mload(0x00)
    11159
                m1 := mload(0x20)
    11160
                m2 := mload(0x40)
    11161
                m3 := mload(0x60)
    11162
                m4 := mload(0x80)
    11163
                m5 := mload(0xa0)
    11164
                m6 := mload(0xc0)
    11165
                // Selector of `log(string,address,uint256,bool)`.
    11166
                mstore(0x00, 0xfc4845f0)
    11167
                mstore(0x20, 0x80)
    11168
                mstore(0x40, p1)
    11169
                mstore(0x60, p2)
    11170
                mstore(0x80, p3)
    11171
                writeString(0xa0, p0)
    11172
            }
    11173
            _sendLogPayload(0x1c, 0xc4);
    11174
            /// @solidity memory-safe-assembly
    11175
            assembly {
    11176
                mstore(0x00, m0)
    11177
                mstore(0x20, m1)
    11178
                mstore(0x40, m2)
    11179
                mstore(0x60, m3)
    11180
                mstore(0x80, m4)
    11181
                mstore(0xa0, m5)
    11182
                mstore(0xc0, m6)
    11183
            }
    11184
        }
    11185
    11186
        function log(bytes32 p0, address p1, uint256 p2, uint256 p3) internal pure {
    11187
            bytes32 m0;
    11188
            bytes32 m1;
    11189
            bytes32 m2;
    11190
            bytes32 m3;
    11191
            bytes32 m4;
    11192
            bytes32 m5;
    11193
            bytes32 m6;
    11194
            /// @solidity memory-safe-assembly
    11195
            assembly {
    11196
                function writeString(pos, w) {
    11197
                    let length := 0
    11198
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    11199
                    mstore(pos, length)
    11200
                    let shift := sub(256, shl(3, length))
    11201
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    11202
                }
    11203
                m0 := mload(0x00)
    11204
                m1 := mload(0x20)
    11205
                m2 := mload(0x40)
    11206
                m3 := mload(0x60)
    11207
                m4 := mload(0x80)
    11208
                m5 := mload(0xa0)
    11209
                m6 := mload(0xc0)
    11210
                // Selector of `log(string,address,uint256,uint256)`.
    11211
                mstore(0x00, 0xf8f51b1e)
    11212
                mstore(0x20, 0x80)
    11213
                mstore(0x40, p1)
    11214
                mstore(0x60, p2)
    11215
                mstore(0x80, p3)
    11216
                writeString(0xa0, p0)
    11217
            }
    11218
            _sendLogPayload(0x1c, 0xc4);
    11219
            /// @solidity memory-safe-assembly
    11220
            assembly {
    11221
                mstore(0x00, m0)
    11222
                mstore(0x20, m1)
    11223
                mstore(0x40, m2)
    11224
                mstore(0x60, m3)
    11225
                mstore(0x80, m4)
    11226
                mstore(0xa0, m5)
    11227
                mstore(0xc0, m6)
    11228
            }
    11229
        }
    11230
    11231
        function log(bytes32 p0, address p1, uint256 p2, bytes32 p3) internal pure {
    11232
            bytes32 m0;
    11233
            bytes32 m1;
    11234
            bytes32 m2;
    11235
            bytes32 m3;
    11236
            bytes32 m4;
    11237
            bytes32 m5;
    11238
            bytes32 m6;
    11239
            bytes32 m7;
    11240
            bytes32 m8;
    11241
            /// @solidity memory-safe-assembly
    11242
            assembly {
    11243
                function writeString(pos, w) {
    11244
                    let length := 0
    11245
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    11246
                    mstore(pos, length)
    11247
                    let shift := sub(256, shl(3, length))
    11248
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    11249
                }
    11250
                m0 := mload(0x00)
    11251
                m1 := mload(0x20)
    11252
                m2 := mload(0x40)
    11253
                m3 := mload(0x60)
    11254
                m4 := mload(0x80)
    11255
                m5 := mload(0xa0)
    11256
                m6 := mload(0xc0)
    11257
                m7 := mload(0xe0)
    11258
                m8 := mload(0x100)
    11259
                // Selector of `log(string,address,uint256,string)`.
    11260
                mstore(0x00, 0x5a477632)
    11261
                mstore(0x20, 0x80)
    11262
                mstore(0x40, p1)
    11263
                mstore(0x60, p2)
    11264
                mstore(0x80, 0xc0)
    11265
                writeString(0xa0, p0)
    11266
                writeString(0xe0, p3)
    11267
            }
    11268
            _sendLogPayload(0x1c, 0x104);
    11269
            /// @solidity memory-safe-assembly
    11270
            assembly {
    11271
                mstore(0x00, m0)
    11272
                mstore(0x20, m1)
    11273
                mstore(0x40, m2)
    11274
                mstore(0x60, m3)
    11275
                mstore(0x80, m4)
    11276
                mstore(0xa0, m5)
    11277
                mstore(0xc0, m6)
    11278
                mstore(0xe0, m7)
    11279
                mstore(0x100, m8)
    11280
            }
    11281
        }
    11282
    11283
        function log(bytes32 p0, address p1, bytes32 p2, address p3) internal pure {
    11284
            bytes32 m0;
    11285
            bytes32 m1;
    11286
            bytes32 m2;
    11287
            bytes32 m3;
    11288
            bytes32 m4;
    11289
            bytes32 m5;
    11290
            bytes32 m6;
    11291
            bytes32 m7;
    11292
            bytes32 m8;
    11293
            /// @solidity memory-safe-assembly
    11294
            assembly {
    11295
                function writeString(pos, w) {
    11296
                    let length := 0
    11297
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    11298
                    mstore(pos, length)
    11299
                    let shift := sub(256, shl(3, length))
    11300
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    11301
                }
    11302
                m0 := mload(0x00)
    11303
                m1 := mload(0x20)
    11304
                m2 := mload(0x40)
    11305
                m3 := mload(0x60)
    11306
                m4 := mload(0x80)
    11307
                m5 := mload(0xa0)
    11308
                m6 := mload(0xc0)
    11309
                m7 := mload(0xe0)
    11310
                m8 := mload(0x100)
    11311
                // Selector of `log(string,address,string,address)`.
    11312
                mstore(0x00, 0xaabc9a31)
    11313
                mstore(0x20, 0x80)
    11314
                mstore(0x40, p1)
    11315
                mstore(0x60, 0xc0)
    11316
                mstore(0x80, p3)
    11317
                writeString(0xa0, p0)
    11318
                writeString(0xe0, p2)
    11319
            }
    11320
            _sendLogPayload(0x1c, 0x104);
    11321
            /// @solidity memory-safe-assembly
    11322
            assembly {
    11323
                mstore(0x00, m0)
    11324
                mstore(0x20, m1)
    11325
                mstore(0x40, m2)
    11326
                mstore(0x60, m3)
    11327
                mstore(0x80, m4)
    11328
                mstore(0xa0, m5)
    11329
                mstore(0xc0, m6)
    11330
                mstore(0xe0, m7)
    11331
                mstore(0x100, m8)
    11332
            }
    11333
        }
    11334
    11335
        function log(bytes32 p0, address p1, bytes32 p2, bool p3) internal pure {
    11336
            bytes32 m0;
    11337
            bytes32 m1;
    11338
            bytes32 m2;
    11339
            bytes32 m3;
    11340
            bytes32 m4;
    11341
            bytes32 m5;
    11342
            bytes32 m6;
    11343
            bytes32 m7;
    11344
            bytes32 m8;
    11345
            /// @solidity memory-safe-assembly
    11346
            assembly {
    11347
                function writeString(pos, w) {
    11348
                    let length := 0
    11349
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    11350
                    mstore(pos, length)
    11351
                    let shift := sub(256, shl(3, length))
    11352
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    11353
                }
    11354
                m0 := mload(0x00)
    11355
                m1 := mload(0x20)
    11356
                m2 := mload(0x40)
    11357
                m3 := mload(0x60)
    11358
                m4 := mload(0x80)
    11359
                m5 := mload(0xa0)
    11360
                m6 := mload(0xc0)
    11361
                m7 := mload(0xe0)
    11362
                m8 := mload(0x100)
    11363
                // Selector of `log(string,address,string,bool)`.
    11364
                mstore(0x00, 0x5f15d28c)
    11365
                mstore(0x20, 0x80)
    11366
                mstore(0x40, p1)
    11367
                mstore(0x60, 0xc0)
    11368
                mstore(0x80, p3)
    11369
                writeString(0xa0, p0)
    11370
                writeString(0xe0, p2)
    11371
            }
    11372
            _sendLogPayload(0x1c, 0x104);
    11373
            /// @solidity memory-safe-assembly
    11374
            assembly {
    11375
                mstore(0x00, m0)
    11376
                mstore(0x20, m1)
    11377
                mstore(0x40, m2)
    11378
                mstore(0x60, m3)
    11379
                mstore(0x80, m4)
    11380
                mstore(0xa0, m5)
    11381
                mstore(0xc0, m6)
    11382
                mstore(0xe0, m7)
    11383
                mstore(0x100, m8)
    11384
            }
    11385
        }
    11386
    11387
        function log(bytes32 p0, address p1, bytes32 p2, uint256 p3) internal pure {
    11388
            bytes32 m0;
    11389
            bytes32 m1;
    11390
            bytes32 m2;
    11391
            bytes32 m3;
    11392
            bytes32 m4;
    11393
            bytes32 m5;
    11394
            bytes32 m6;
    11395
            bytes32 m7;
    11396
            bytes32 m8;
    11397
            /// @solidity memory-safe-assembly
    11398
            assembly {
    11399
                function writeString(pos, w) {
    11400
                    let length := 0
    11401
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    11402
                    mstore(pos, length)
    11403
                    let shift := sub(256, shl(3, length))
    11404
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    11405
                }
    11406
                m0 := mload(0x00)
    11407
                m1 := mload(0x20)
    11408
                m2 := mload(0x40)
    11409
                m3 := mload(0x60)
    11410
                m4 := mload(0x80)
    11411
                m5 := mload(0xa0)
    11412
                m6 := mload(0xc0)
    11413
                m7 := mload(0xe0)
    11414
                m8 := mload(0x100)
    11415
                // Selector of `log(string,address,string,uint256)`.
    11416
                mstore(0x00, 0x91d1112e)
    11417
                mstore(0x20, 0x80)
    11418
                mstore(0x40, p1)
    11419
                mstore(0x60, 0xc0)
    11420
                mstore(0x80, p3)
    11421
                writeString(0xa0, p0)
    11422
                writeString(0xe0, p2)
    11423
            }
    11424
            _sendLogPayload(0x1c, 0x104);
    11425
            /// @solidity memory-safe-assembly
    11426
            assembly {
    11427
                mstore(0x00, m0)
    11428
                mstore(0x20, m1)
    11429
                mstore(0x40, m2)
    11430
                mstore(0x60, m3)
    11431
                mstore(0x80, m4)
    11432
                mstore(0xa0, m5)
    11433
                mstore(0xc0, m6)
    11434
                mstore(0xe0, m7)
    11435
                mstore(0x100, m8)
    11436
            }
    11437
        }
    11438
    11439
        function log(bytes32 p0, address p1, bytes32 p2, bytes32 p3) internal pure {
    11440
            bytes32 m0;
    11441
            bytes32 m1;
    11442
            bytes32 m2;
    11443
            bytes32 m3;
    11444
            bytes32 m4;
    11445
            bytes32 m5;
    11446
            bytes32 m6;
    11447
            bytes32 m7;
    11448
            bytes32 m8;
    11449
            bytes32 m9;
    11450
            bytes32 m10;
    11451
            /// @solidity memory-safe-assembly
    11452
            assembly {
    11453
                function writeString(pos, w) {
    11454
                    let length := 0
    11455
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    11456
                    mstore(pos, length)
    11457
                    let shift := sub(256, shl(3, length))
    11458
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    11459
                }
    11460
                m0 := mload(0x00)
    11461
                m1 := mload(0x20)
    11462
                m2 := mload(0x40)
    11463
                m3 := mload(0x60)
    11464
                m4 := mload(0x80)
    11465
                m5 := mload(0xa0)
    11466
                m6 := mload(0xc0)
    11467
                m7 := mload(0xe0)
    11468
                m8 := mload(0x100)
    11469
                m9 := mload(0x120)
    11470
                m10 := mload(0x140)
    11471
                // Selector of `log(string,address,string,string)`.
    11472
                mstore(0x00, 0x245986f2)
    11473
                mstore(0x20, 0x80)
    11474
                mstore(0x40, p1)
    11475
                mstore(0x60, 0xc0)
    11476
                mstore(0x80, 0x100)
    11477
                writeString(0xa0, p0)
    11478
                writeString(0xe0, p2)
    11479
                writeString(0x120, p3)
    11480
            }
    11481
            _sendLogPayload(0x1c, 0x144);
    11482
            /// @solidity memory-safe-assembly
    11483
            assembly {
    11484
                mstore(0x00, m0)
    11485
                mstore(0x20, m1)
    11486
                mstore(0x40, m2)
    11487
                mstore(0x60, m3)
    11488
                mstore(0x80, m4)
    11489
                mstore(0xa0, m5)
    11490
                mstore(0xc0, m6)
    11491
                mstore(0xe0, m7)
    11492
                mstore(0x100, m8)
    11493
                mstore(0x120, m9)
    11494
                mstore(0x140, m10)
    11495
            }
    11496
        }
    11497
    11498
        function log(bytes32 p0, bool p1, address p2, address p3) internal pure {
    11499
            bytes32 m0;
    11500
            bytes32 m1;
    11501
            bytes32 m2;
    11502
            bytes32 m3;
    11503
            bytes32 m4;
    11504
            bytes32 m5;
    11505
            bytes32 m6;
    11506
            /// @solidity memory-safe-assembly
    11507
            assembly {
    11508
                function writeString(pos, w) {
    11509
                    let length := 0
    11510
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    11511
                    mstore(pos, length)
    11512
                    let shift := sub(256, shl(3, length))
    11513
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    11514
                }
    11515
                m0 := mload(0x00)
    11516
                m1 := mload(0x20)
    11517
                m2 := mload(0x40)
    11518
                m3 := mload(0x60)
    11519
                m4 := mload(0x80)
    11520
                m5 := mload(0xa0)
    11521
                m6 := mload(0xc0)
    11522
                // Selector of `log(string,bool,address,address)`.
    11523
                mstore(0x00, 0x33e9dd1d)
    11524
                mstore(0x20, 0x80)
    11525
                mstore(0x40, p1)
    11526
                mstore(0x60, p2)
    11527
                mstore(0x80, p3)
    11528
                writeString(0xa0, p0)
    11529
            }
    11530
            _sendLogPayload(0x1c, 0xc4);
    11531
            /// @solidity memory-safe-assembly
    11532
            assembly {
    11533
                mstore(0x00, m0)
    11534
                mstore(0x20, m1)
    11535
                mstore(0x40, m2)
    11536
                mstore(0x60, m3)
    11537
                mstore(0x80, m4)
    11538
                mstore(0xa0, m5)
    11539
                mstore(0xc0, m6)
    11540
            }
    11541
        }
    11542
    11543
        function log(bytes32 p0, bool p1, address p2, bool p3) internal pure {
    11544
            bytes32 m0;
    11545
            bytes32 m1;
    11546
            bytes32 m2;
    11547
            bytes32 m3;
    11548
            bytes32 m4;
    11549
            bytes32 m5;
    11550
            bytes32 m6;
    11551
            /// @solidity memory-safe-assembly
    11552
            assembly {
    11553
                function writeString(pos, w) {
    11554
                    let length := 0
    11555
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    11556
                    mstore(pos, length)
    11557
                    let shift := sub(256, shl(3, length))
    11558
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    11559
                }
    11560
                m0 := mload(0x00)
    11561
                m1 := mload(0x20)
    11562
                m2 := mload(0x40)
    11563
                m3 := mload(0x60)
    11564
                m4 := mload(0x80)
    11565
                m5 := mload(0xa0)
    11566
                m6 := mload(0xc0)
    11567
                // Selector of `log(string,bool,address,bool)`.
    11568
                mstore(0x00, 0x958c28c6)
    11569
                mstore(0x20, 0x80)
    11570
                mstore(0x40, p1)
    11571
                mstore(0x60, p2)
    11572
                mstore(0x80, p3)
    11573
                writeString(0xa0, p0)
    11574
            }
    11575
            _sendLogPayload(0x1c, 0xc4);
    11576
            /// @solidity memory-safe-assembly
    11577
            assembly {
    11578
                mstore(0x00, m0)
    11579
                mstore(0x20, m1)
    11580
                mstore(0x40, m2)
    11581
                mstore(0x60, m3)
    11582
                mstore(0x80, m4)
    11583
                mstore(0xa0, m5)
    11584
                mstore(0xc0, m6)
    11585
            }
    11586
        }
    11587
    11588
        function log(bytes32 p0, bool p1, address p2, uint256 p3) internal pure {
    11589
            bytes32 m0;
    11590
            bytes32 m1;
    11591
            bytes32 m2;
    11592
            bytes32 m3;
    11593
            bytes32 m4;
    11594
            bytes32 m5;
    11595
            bytes32 m6;
    11596
            /// @solidity memory-safe-assembly
    11597
            assembly {
    11598
                function writeString(pos, w) {
    11599
                    let length := 0
    11600
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    11601
                    mstore(pos, length)
    11602
                    let shift := sub(256, shl(3, length))
    11603
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    11604
                }
    11605
                m0 := mload(0x00)
    11606
                m1 := mload(0x20)
    11607
                m2 := mload(0x40)
    11608
                m3 := mload(0x60)
    11609
                m4 := mload(0x80)
    11610
                m5 := mload(0xa0)
    11611
                m6 := mload(0xc0)
    11612
                // Selector of `log(string,bool,address,uint256)`.
    11613
                mstore(0x00, 0x5d08bb05)
    11614
                mstore(0x20, 0x80)
    11615
                mstore(0x40, p1)
    11616
                mstore(0x60, p2)
    11617
                mstore(0x80, p3)
    11618
                writeString(0xa0, p0)
    11619
            }
    11620
            _sendLogPayload(0x1c, 0xc4);
    11621
            /// @solidity memory-safe-assembly
    11622
            assembly {
    11623
                mstore(0x00, m0)
    11624
                mstore(0x20, m1)
    11625
                mstore(0x40, m2)
    11626
                mstore(0x60, m3)
    11627
                mstore(0x80, m4)
    11628
                mstore(0xa0, m5)
    11629
                mstore(0xc0, m6)
    11630
            }
    11631
        }
    11632
    11633
        function log(bytes32 p0, bool p1, address p2, bytes32 p3) internal pure {
    11634
            bytes32 m0;
    11635
            bytes32 m1;
    11636
            bytes32 m2;
    11637
            bytes32 m3;
    11638
            bytes32 m4;
    11639
            bytes32 m5;
    11640
            bytes32 m6;
    11641
            bytes32 m7;
    11642
            bytes32 m8;
    11643
            /// @solidity memory-safe-assembly
    11644
            assembly {
    11645
                function writeString(pos, w) {
    11646
                    let length := 0
    11647
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    11648
                    mstore(pos, length)
    11649
                    let shift := sub(256, shl(3, length))
    11650
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    11651
                }
    11652
                m0 := mload(0x00)
    11653
                m1 := mload(0x20)
    11654
                m2 := mload(0x40)
    11655
                m3 := mload(0x60)
    11656
                m4 := mload(0x80)
    11657
                m5 := mload(0xa0)
    11658
                m6 := mload(0xc0)
    11659
                m7 := mload(0xe0)
    11660
                m8 := mload(0x100)
    11661
                // Selector of `log(string,bool,address,string)`.
    11662
                mstore(0x00, 0x2d8e33a4)
    11663
                mstore(0x20, 0x80)
    11664
                mstore(0x40, p1)
    11665
                mstore(0x60, p2)
    11666
                mstore(0x80, 0xc0)
    11667
                writeString(0xa0, p0)
    11668
                writeString(0xe0, p3)
    11669
            }
    11670
            _sendLogPayload(0x1c, 0x104);
    11671
            /// @solidity memory-safe-assembly
    11672
            assembly {
    11673
                mstore(0x00, m0)
    11674
                mstore(0x20, m1)
    11675
                mstore(0x40, m2)
    11676
                mstore(0x60, m3)
    11677
                mstore(0x80, m4)
    11678
                mstore(0xa0, m5)
    11679
                mstore(0xc0, m6)
    11680
                mstore(0xe0, m7)
    11681
                mstore(0x100, m8)
    11682
            }
    11683
        }
    11684
    11685
        function log(bytes32 p0, bool p1, bool p2, address p3) internal pure {
    11686
            bytes32 m0;
    11687
            bytes32 m1;
    11688
            bytes32 m2;
    11689
            bytes32 m3;
    11690
            bytes32 m4;
    11691
            bytes32 m5;
    11692
            bytes32 m6;
    11693
            /// @solidity memory-safe-assembly
    11694
            assembly {
    11695
                function writeString(pos, w) {
    11696
                    let length := 0
    11697
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    11698
                    mstore(pos, length)
    11699
                    let shift := sub(256, shl(3, length))
    11700
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    11701
                }
    11702
                m0 := mload(0x00)
    11703
                m1 := mload(0x20)
    11704
                m2 := mload(0x40)
    11705
                m3 := mload(0x60)
    11706
                m4 := mload(0x80)
    11707
                m5 := mload(0xa0)
    11708
                m6 := mload(0xc0)
    11709
                // Selector of `log(string,bool,bool,address)`.
    11710
                mstore(0x00, 0x7190a529)
    11711
                mstore(0x20, 0x80)
    11712
                mstore(0x40, p1)
    11713
                mstore(0x60, p2)
    11714
                mstore(0x80, p3)
    11715
                writeString(0xa0, p0)
    11716
            }
    11717
            _sendLogPayload(0x1c, 0xc4);
    11718
            /// @solidity memory-safe-assembly
    11719
            assembly {
    11720
                mstore(0x00, m0)
    11721
                mstore(0x20, m1)
    11722
                mstore(0x40, m2)
    11723
                mstore(0x60, m3)
    11724
                mstore(0x80, m4)
    11725
                mstore(0xa0, m5)
    11726
                mstore(0xc0, m6)
    11727
            }
    11728
        }
    11729
    11730
        function log(bytes32 p0, bool p1, bool p2, bool p3) internal pure {
    11731
            bytes32 m0;
    11732
            bytes32 m1;
    11733
            bytes32 m2;
    11734
            bytes32 m3;
    11735
            bytes32 m4;
    11736
            bytes32 m5;
    11737
            bytes32 m6;
    11738
            /// @solidity memory-safe-assembly
    11739
            assembly {
    11740
                function writeString(pos, w) {
    11741
                    let length := 0
    11742
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    11743
                    mstore(pos, length)
    11744
                    let shift := sub(256, shl(3, length))
    11745
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    11746
                }
    11747
                m0 := mload(0x00)
    11748
                m1 := mload(0x20)
    11749
                m2 := mload(0x40)
    11750
                m3 := mload(0x60)
    11751
                m4 := mload(0x80)
    11752
                m5 := mload(0xa0)
    11753
                m6 := mload(0xc0)
    11754
                // Selector of `log(string,bool,bool,bool)`.
    11755
                mstore(0x00, 0x895af8c5)
    11756
                mstore(0x20, 0x80)
    11757
                mstore(0x40, p1)
    11758
                mstore(0x60, p2)
    11759
                mstore(0x80, p3)
    11760
                writeString(0xa0, p0)
    11761
            }
    11762
            _sendLogPayload(0x1c, 0xc4);
    11763
            /// @solidity memory-safe-assembly
    11764
            assembly {
    11765
                mstore(0x00, m0)
    11766
                mstore(0x20, m1)
    11767
                mstore(0x40, m2)
    11768
                mstore(0x60, m3)
    11769
                mstore(0x80, m4)
    11770
                mstore(0xa0, m5)
    11771
                mstore(0xc0, m6)
    11772
            }
    11773
        }
    11774
    11775
        function log(bytes32 p0, bool p1, bool p2, uint256 p3) internal pure {
    11776
            bytes32 m0;
    11777
            bytes32 m1;
    11778
            bytes32 m2;
    11779
            bytes32 m3;
    11780
            bytes32 m4;
    11781
            bytes32 m5;
    11782
            bytes32 m6;
    11783
            /// @solidity memory-safe-assembly
    11784
            assembly {
    11785
                function writeString(pos, w) {
    11786
                    let length := 0
    11787
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    11788
                    mstore(pos, length)
    11789
                    let shift := sub(256, shl(3, length))
    11790
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    11791
                }
    11792
                m0 := mload(0x00)
    11793
                m1 := mload(0x20)
    11794
                m2 := mload(0x40)
    11795
                m3 := mload(0x60)
    11796
                m4 := mload(0x80)
    11797
                m5 := mload(0xa0)
    11798
                m6 := mload(0xc0)
    11799
                // Selector of `log(string,bool,bool,uint256)`.
    11800
                mstore(0x00, 0x8e3f78a9)
    11801
                mstore(0x20, 0x80)
    11802
                mstore(0x40, p1)
    11803
                mstore(0x60, p2)
    11804
                mstore(0x80, p3)
    11805
                writeString(0xa0, p0)
    11806
            }
    11807
            _sendLogPayload(0x1c, 0xc4);
    11808
            /// @solidity memory-safe-assembly
    11809
            assembly {
    11810
                mstore(0x00, m0)
    11811
                mstore(0x20, m1)
    11812
                mstore(0x40, m2)
    11813
                mstore(0x60, m3)
    11814
                mstore(0x80, m4)
    11815
                mstore(0xa0, m5)
    11816
                mstore(0xc0, m6)
    11817
            }
    11818
        }
    11819
    11820
        function log(bytes32 p0, bool p1, bool p2, bytes32 p3) internal pure {
    11821
            bytes32 m0;
    11822
            bytes32 m1;
    11823
            bytes32 m2;
    11824
            bytes32 m3;
    11825
            bytes32 m4;
    11826
            bytes32 m5;
    11827
            bytes32 m6;
    11828
            bytes32 m7;
    11829
            bytes32 m8;
    11830
            /// @solidity memory-safe-assembly
    11831
            assembly {
    11832
                function writeString(pos, w) {
    11833
                    let length := 0
    11834
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    11835
                    mstore(pos, length)
    11836
                    let shift := sub(256, shl(3, length))
    11837
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    11838
                }
    11839
                m0 := mload(0x00)
    11840
                m1 := mload(0x20)
    11841
                m2 := mload(0x40)
    11842
                m3 := mload(0x60)
    11843
                m4 := mload(0x80)
    11844
                m5 := mload(0xa0)
    11845
                m6 := mload(0xc0)
    11846
                m7 := mload(0xe0)
    11847
                m8 := mload(0x100)
    11848
                // Selector of `log(string,bool,bool,string)`.
    11849
                mstore(0x00, 0x9d22d5dd)
    11850
                mstore(0x20, 0x80)
    11851
                mstore(0x40, p1)
    11852
                mstore(0x60, p2)
    11853
                mstore(0x80, 0xc0)
    11854
                writeString(0xa0, p0)
    11855
                writeString(0xe0, p3)
    11856
            }
    11857
            _sendLogPayload(0x1c, 0x104);
    11858
            /// @solidity memory-safe-assembly
    11859
            assembly {
    11860
                mstore(0x00, m0)
    11861
                mstore(0x20, m1)
    11862
                mstore(0x40, m2)
    11863
                mstore(0x60, m3)
    11864
                mstore(0x80, m4)
    11865
                mstore(0xa0, m5)
    11866
                mstore(0xc0, m6)
    11867
                mstore(0xe0, m7)
    11868
                mstore(0x100, m8)
    11869
            }
    11870
        }
    11871
    11872
        function log(bytes32 p0, bool p1, uint256 p2, address p3) internal pure {
    11873
            bytes32 m0;
    11874
            bytes32 m1;
    11875
            bytes32 m2;
    11876
            bytes32 m3;
    11877
            bytes32 m4;
    11878
            bytes32 m5;
    11879
            bytes32 m6;
    11880
            /// @solidity memory-safe-assembly
    11881
            assembly {
    11882
                function writeString(pos, w) {
    11883
                    let length := 0
    11884
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    11885
                    mstore(pos, length)
    11886
                    let shift := sub(256, shl(3, length))
    11887
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    11888
                }
    11889
                m0 := mload(0x00)
    11890
                m1 := mload(0x20)
    11891
                m2 := mload(0x40)
    11892
                m3 := mload(0x60)
    11893
                m4 := mload(0x80)
    11894
                m5 := mload(0xa0)
    11895
                m6 := mload(0xc0)
    11896
                // Selector of `log(string,bool,uint256,address)`.
    11897
                mstore(0x00, 0x935e09bf)
    11898
                mstore(0x20, 0x80)
    11899
                mstore(0x40, p1)
    11900
                mstore(0x60, p2)
    11901
                mstore(0x80, p3)
    11902
                writeString(0xa0, p0)
    11903
            }
    11904
            _sendLogPayload(0x1c, 0xc4);
    11905
            /// @solidity memory-safe-assembly
    11906
            assembly {
    11907
                mstore(0x00, m0)
    11908
                mstore(0x20, m1)
    11909
                mstore(0x40, m2)
    11910
                mstore(0x60, m3)
    11911
                mstore(0x80, m4)
    11912
                mstore(0xa0, m5)
    11913
                mstore(0xc0, m6)
    11914
            }
    11915
        }
    11916
    11917
        function log(bytes32 p0, bool p1, uint256 p2, bool p3) internal pure {
    11918
            bytes32 m0;
    11919
            bytes32 m1;
    11920
            bytes32 m2;
    11921
            bytes32 m3;
    11922
            bytes32 m4;
    11923
            bytes32 m5;
    11924
            bytes32 m6;
    11925
            /// @solidity memory-safe-assembly
    11926
            assembly {
    11927
                function writeString(pos, w) {
    11928
                    let length := 0
    11929
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    11930
                    mstore(pos, length)
    11931
                    let shift := sub(256, shl(3, length))
    11932
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    11933
                }
    11934
                m0 := mload(0x00)
    11935
                m1 := mload(0x20)
    11936
                m2 := mload(0x40)
    11937
                m3 := mload(0x60)
    11938
                m4 := mload(0x80)
    11939
                m5 := mload(0xa0)
    11940
                m6 := mload(0xc0)
    11941
                // Selector of `log(string,bool,uint256,bool)`.
    11942
                mstore(0x00, 0x8af7cf8a)
    11943
                mstore(0x20, 0x80)
    11944
                mstore(0x40, p1)
    11945
                mstore(0x60, p2)
    11946
                mstore(0x80, p3)
    11947
                writeString(0xa0, p0)
    11948
            }
    11949
            _sendLogPayload(0x1c, 0xc4);
    11950
            /// @solidity memory-safe-assembly
    11951
            assembly {
    11952
                mstore(0x00, m0)
    11953
                mstore(0x20, m1)
    11954
                mstore(0x40, m2)
    11955
                mstore(0x60, m3)
    11956
                mstore(0x80, m4)
    11957
                mstore(0xa0, m5)
    11958
                mstore(0xc0, m6)
    11959
            }
    11960
        }
    11961
    11962
        function log(bytes32 p0, bool p1, uint256 p2, uint256 p3) internal pure {
    11963
            bytes32 m0;
    11964
            bytes32 m1;
    11965
            bytes32 m2;
    11966
            bytes32 m3;
    11967
            bytes32 m4;
    11968
            bytes32 m5;
    11969
            bytes32 m6;
    11970
            /// @solidity memory-safe-assembly
    11971
            assembly {
    11972
                function writeString(pos, w) {
    11973
                    let length := 0
    11974
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    11975
                    mstore(pos, length)
    11976
                    let shift := sub(256, shl(3, length))
    11977
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    11978
                }
    11979
                m0 := mload(0x00)
    11980
                m1 := mload(0x20)
    11981
                m2 := mload(0x40)
    11982
                m3 := mload(0x60)
    11983
                m4 := mload(0x80)
    11984
                m5 := mload(0xa0)
    11985
                m6 := mload(0xc0)
    11986
                // Selector of `log(string,bool,uint256,uint256)`.
    11987
                mstore(0x00, 0x64b5bb67)
    11988
                mstore(0x20, 0x80)
    11989
                mstore(0x40, p1)
    11990
                mstore(0x60, p2)
    11991
                mstore(0x80, p3)
    11992
                writeString(0xa0, p0)
    11993
            }
    11994
            _sendLogPayload(0x1c, 0xc4);
    11995
            /// @solidity memory-safe-assembly
    11996
            assembly {
    11997
                mstore(0x00, m0)
    11998
                mstore(0x20, m1)
    11999
                mstore(0x40, m2)
    12000
                mstore(0x60, m3)
    12001
                mstore(0x80, m4)
    12002
                mstore(0xa0, m5)
    12003
                mstore(0xc0, m6)
    12004
            }
    12005
        }
    12006
    12007
        function log(bytes32 p0, bool p1, uint256 p2, bytes32 p3) internal pure {
    12008
            bytes32 m0;
    12009
            bytes32 m1;
    12010
            bytes32 m2;
    12011
            bytes32 m3;
    12012
            bytes32 m4;
    12013
            bytes32 m5;
    12014
            bytes32 m6;
    12015
            bytes32 m7;
    12016
            bytes32 m8;
    12017
            /// @solidity memory-safe-assembly
    12018
            assembly {
    12019
                function writeString(pos, w) {
    12020
                    let length := 0
    12021
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    12022
                    mstore(pos, length)
    12023
                    let shift := sub(256, shl(3, length))
    12024
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    12025
                }
    12026
                m0 := mload(0x00)
    12027
                m1 := mload(0x20)
    12028
                m2 := mload(0x40)
    12029
                m3 := mload(0x60)
    12030
                m4 := mload(0x80)
    12031
                m5 := mload(0xa0)
    12032
                m6 := mload(0xc0)
    12033
                m7 := mload(0xe0)
    12034
                m8 := mload(0x100)
    12035
                // Selector of `log(string,bool,uint256,string)`.
    12036
                mstore(0x00, 0x742d6ee7)
    12037
                mstore(0x20, 0x80)
    12038
                mstore(0x40, p1)
    12039
                mstore(0x60, p2)
    12040
                mstore(0x80, 0xc0)
    12041
                writeString(0xa0, p0)
    12042
                writeString(0xe0, p3)
    12043
            }
    12044
            _sendLogPayload(0x1c, 0x104);
    12045
            /// @solidity memory-safe-assembly
    12046
            assembly {
    12047
                mstore(0x00, m0)
    12048
                mstore(0x20, m1)
    12049
                mstore(0x40, m2)
    12050
                mstore(0x60, m3)
    12051
                mstore(0x80, m4)
    12052
                mstore(0xa0, m5)
    12053
                mstore(0xc0, m6)
    12054
                mstore(0xe0, m7)
    12055
                mstore(0x100, m8)
    12056
            }
    12057
        }
    12058
    12059
        function log(bytes32 p0, bool p1, bytes32 p2, address p3) internal pure {
    12060
            bytes32 m0;
    12061
            bytes32 m1;
    12062
            bytes32 m2;
    12063
            bytes32 m3;
    12064
            bytes32 m4;
    12065
            bytes32 m5;
    12066
            bytes32 m6;
    12067
            bytes32 m7;
    12068
            bytes32 m8;
    12069
            /// @solidity memory-safe-assembly
    12070
            assembly {
    12071
                function writeString(pos, w) {
    12072
                    let length := 0
    12073
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    12074
                    mstore(pos, length)
    12075
                    let shift := sub(256, shl(3, length))
    12076
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    12077
                }
    12078
                m0 := mload(0x00)
    12079
                m1 := mload(0x20)
    12080
                m2 := mload(0x40)
    12081
                m3 := mload(0x60)
    12082
                m4 := mload(0x80)
    12083
                m5 := mload(0xa0)
    12084
                m6 := mload(0xc0)
    12085
                m7 := mload(0xe0)
    12086
                m8 := mload(0x100)
    12087
                // Selector of `log(string,bool,string,address)`.
    12088
                mstore(0x00, 0xe0625b29)
    12089
                mstore(0x20, 0x80)
    12090
                mstore(0x40, p1)
    12091
                mstore(0x60, 0xc0)
    12092
                mstore(0x80, p3)
    12093
                writeString(0xa0, p0)
    12094
                writeString(0xe0, p2)
    12095
            }
    12096
            _sendLogPayload(0x1c, 0x104);
    12097
            /// @solidity memory-safe-assembly
    12098
            assembly {
    12099
                mstore(0x00, m0)
    12100
                mstore(0x20, m1)
    12101
                mstore(0x40, m2)
    12102
                mstore(0x60, m3)
    12103
                mstore(0x80, m4)
    12104
                mstore(0xa0, m5)
    12105
                mstore(0xc0, m6)
    12106
                mstore(0xe0, m7)
    12107
                mstore(0x100, m8)
    12108
            }
    12109
        }
    12110
    12111
        function log(bytes32 p0, bool p1, bytes32 p2, bool p3) internal pure {
    12112
            bytes32 m0;
    12113
            bytes32 m1;
    12114
            bytes32 m2;
    12115
            bytes32 m3;
    12116
            bytes32 m4;
    12117
            bytes32 m5;
    12118
            bytes32 m6;
    12119
            bytes32 m7;
    12120
            bytes32 m8;
    12121
            /// @solidity memory-safe-assembly
    12122
            assembly {
    12123
                function writeString(pos, w) {
    12124
                    let length := 0
    12125
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    12126
                    mstore(pos, length)
    12127
                    let shift := sub(256, shl(3, length))
    12128
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    12129
                }
    12130
                m0 := mload(0x00)
    12131
                m1 := mload(0x20)
    12132
                m2 := mload(0x40)
    12133
                m3 := mload(0x60)
    12134
                m4 := mload(0x80)
    12135
                m5 := mload(0xa0)
    12136
                m6 := mload(0xc0)
    12137
                m7 := mload(0xe0)
    12138
                m8 := mload(0x100)
    12139
                // Selector of `log(string,bool,string,bool)`.
    12140
                mstore(0x00, 0x3f8a701d)
    12141
                mstore(0x20, 0x80)
    12142
                mstore(0x40, p1)
    12143
                mstore(0x60, 0xc0)
    12144
                mstore(0x80, p3)
    12145
                writeString(0xa0, p0)
    12146
                writeString(0xe0, p2)
    12147
            }
    12148
            _sendLogPayload(0x1c, 0x104);
    12149
            /// @solidity memory-safe-assembly
    12150
            assembly {
    12151
                mstore(0x00, m0)
    12152
                mstore(0x20, m1)
    12153
                mstore(0x40, m2)
    12154
                mstore(0x60, m3)
    12155
                mstore(0x80, m4)
    12156
                mstore(0xa0, m5)
    12157
                mstore(0xc0, m6)
    12158
                mstore(0xe0, m7)
    12159
                mstore(0x100, m8)
    12160
            }
    12161
        }
    12162
    12163
        function log(bytes32 p0, bool p1, bytes32 p2, uint256 p3) internal pure {
    12164
            bytes32 m0;
    12165
            bytes32 m1;
    12166
            bytes32 m2;
    12167
            bytes32 m3;
    12168
            bytes32 m4;
    12169
            bytes32 m5;
    12170
            bytes32 m6;
    12171
            bytes32 m7;
    12172
            bytes32 m8;
    12173
            /// @solidity memory-safe-assembly
    12174
            assembly {
    12175
                function writeString(pos, w) {
    12176
                    let length := 0
    12177
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    12178
                    mstore(pos, length)
    12179
                    let shift := sub(256, shl(3, length))
    12180
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    12181
                }
    12182
                m0 := mload(0x00)
    12183
                m1 := mload(0x20)
    12184
                m2 := mload(0x40)
    12185
                m3 := mload(0x60)
    12186
                m4 := mload(0x80)
    12187
                m5 := mload(0xa0)
    12188
                m6 := mload(0xc0)
    12189
                m7 := mload(0xe0)
    12190
                m8 := mload(0x100)
    12191
                // Selector of `log(string,bool,string,uint256)`.
    12192
                mstore(0x00, 0x24f91465)
    12193
                mstore(0x20, 0x80)
    12194
                mstore(0x40, p1)
    12195
                mstore(0x60, 0xc0)
    12196
                mstore(0x80, p3)
    12197
                writeString(0xa0, p0)
    12198
                writeString(0xe0, p2)
    12199
            }
    12200
            _sendLogPayload(0x1c, 0x104);
    12201
            /// @solidity memory-safe-assembly
    12202
            assembly {
    12203
                mstore(0x00, m0)
    12204
                mstore(0x20, m1)
    12205
                mstore(0x40, m2)
    12206
                mstore(0x60, m3)
    12207
                mstore(0x80, m4)
    12208
                mstore(0xa0, m5)
    12209
                mstore(0xc0, m6)
    12210
                mstore(0xe0, m7)
    12211
                mstore(0x100, m8)
    12212
            }
    12213
        }
    12214
    12215
        function log(bytes32 p0, bool p1, bytes32 p2, bytes32 p3) internal pure {
    12216
            bytes32 m0;
    12217
            bytes32 m1;
    12218
            bytes32 m2;
    12219
            bytes32 m3;
    12220
            bytes32 m4;
    12221
            bytes32 m5;
    12222
            bytes32 m6;
    12223
            bytes32 m7;
    12224
            bytes32 m8;
    12225
            bytes32 m9;
    12226
            bytes32 m10;
    12227
            /// @solidity memory-safe-assembly
    12228
            assembly {
    12229
                function writeString(pos, w) {
    12230
                    let length := 0
    12231
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    12232
                    mstore(pos, length)
    12233
                    let shift := sub(256, shl(3, length))
    12234
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    12235
                }
    12236
                m0 := mload(0x00)
    12237
                m1 := mload(0x20)
    12238
                m2 := mload(0x40)
    12239
                m3 := mload(0x60)
    12240
                m4 := mload(0x80)
    12241
                m5 := mload(0xa0)
    12242
                m6 := mload(0xc0)
    12243
                m7 := mload(0xe0)
    12244
                m8 := mload(0x100)
    12245
                m9 := mload(0x120)
    12246
                m10 := mload(0x140)
    12247
                // Selector of `log(string,bool,string,string)`.
    12248
                mstore(0x00, 0xa826caeb)
    12249
                mstore(0x20, 0x80)
    12250
                mstore(0x40, p1)
    12251
                mstore(0x60, 0xc0)
    12252
                mstore(0x80, 0x100)
    12253
                writeString(0xa0, p0)
    12254
                writeString(0xe0, p2)
    12255
                writeString(0x120, p3)
    12256
            }
    12257
            _sendLogPayload(0x1c, 0x144);
    12258
            /// @solidity memory-safe-assembly
    12259
            assembly {
    12260
                mstore(0x00, m0)
    12261
                mstore(0x20, m1)
    12262
                mstore(0x40, m2)
    12263
                mstore(0x60, m3)
    12264
                mstore(0x80, m4)
    12265
                mstore(0xa0, m5)
    12266
                mstore(0xc0, m6)
    12267
                mstore(0xe0, m7)
    12268
                mstore(0x100, m8)
    12269
                mstore(0x120, m9)
    12270
                mstore(0x140, m10)
    12271
            }
    12272
        }
    12273
    12274
        function log(bytes32 p0, uint256 p1, address p2, address p3) internal pure {
    12275
            bytes32 m0;
    12276
            bytes32 m1;
    12277
            bytes32 m2;
    12278
            bytes32 m3;
    12279
            bytes32 m4;
    12280
            bytes32 m5;
    12281
            bytes32 m6;
    12282
            /// @solidity memory-safe-assembly
    12283
            assembly {
    12284
                function writeString(pos, w) {
    12285
                    let length := 0
    12286
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    12287
                    mstore(pos, length)
    12288
                    let shift := sub(256, shl(3, length))
    12289
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    12290
                }
    12291
                m0 := mload(0x00)
    12292
                m1 := mload(0x20)
    12293
                m2 := mload(0x40)
    12294
                m3 := mload(0x60)
    12295
                m4 := mload(0x80)
    12296
                m5 := mload(0xa0)
    12297
                m6 := mload(0xc0)
    12298
                // Selector of `log(string,uint256,address,address)`.
    12299
                mstore(0x00, 0x5ea2b7ae)
    12300
                mstore(0x20, 0x80)
    12301
                mstore(0x40, p1)
    12302
                mstore(0x60, p2)
    12303
                mstore(0x80, p3)
    12304
                writeString(0xa0, p0)
    12305
            }
    12306
            _sendLogPayload(0x1c, 0xc4);
    12307
            /// @solidity memory-safe-assembly
    12308
            assembly {
    12309
                mstore(0x00, m0)
    12310
                mstore(0x20, m1)
    12311
                mstore(0x40, m2)
    12312
                mstore(0x60, m3)
    12313
                mstore(0x80, m4)
    12314
                mstore(0xa0, m5)
    12315
                mstore(0xc0, m6)
    12316
            }
    12317
        }
    12318
    12319
        function log(bytes32 p0, uint256 p1, address p2, bool p3) internal pure {
    12320
            bytes32 m0;
    12321
            bytes32 m1;
    12322
            bytes32 m2;
    12323
            bytes32 m3;
    12324
            bytes32 m4;
    12325
            bytes32 m5;
    12326
            bytes32 m6;
    12327
            /// @solidity memory-safe-assembly
    12328
            assembly {
    12329
                function writeString(pos, w) {
    12330
                    let length := 0
    12331
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    12332
                    mstore(pos, length)
    12333
                    let shift := sub(256, shl(3, length))
    12334
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    12335
                }
    12336
                m0 := mload(0x00)
    12337
                m1 := mload(0x20)
    12338
                m2 := mload(0x40)
    12339
                m3 := mload(0x60)
    12340
                m4 := mload(0x80)
    12341
                m5 := mload(0xa0)
    12342
                m6 := mload(0xc0)
    12343
                // Selector of `log(string,uint256,address,bool)`.
    12344
                mstore(0x00, 0x82112a42)
    12345
                mstore(0x20, 0x80)
    12346
                mstore(0x40, p1)
    12347
                mstore(0x60, p2)
    12348
                mstore(0x80, p3)
    12349
                writeString(0xa0, p0)
    12350
            }
    12351
            _sendLogPayload(0x1c, 0xc4);
    12352
            /// @solidity memory-safe-assembly
    12353
            assembly {
    12354
                mstore(0x00, m0)
    12355
                mstore(0x20, m1)
    12356
                mstore(0x40, m2)
    12357
                mstore(0x60, m3)
    12358
                mstore(0x80, m4)
    12359
                mstore(0xa0, m5)
    12360
                mstore(0xc0, m6)
    12361
            }
    12362
        }
    12363
    12364
        function log(bytes32 p0, uint256 p1, address p2, uint256 p3) internal pure {
    12365
            bytes32 m0;
    12366
            bytes32 m1;
    12367
            bytes32 m2;
    12368
            bytes32 m3;
    12369
            bytes32 m4;
    12370
            bytes32 m5;
    12371
            bytes32 m6;
    12372
            /// @solidity memory-safe-assembly
    12373
            assembly {
    12374
                function writeString(pos, w) {
    12375
                    let length := 0
    12376
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    12377
                    mstore(pos, length)
    12378
                    let shift := sub(256, shl(3, length))
    12379
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    12380
                }
    12381
                m0 := mload(0x00)
    12382
                m1 := mload(0x20)
    12383
                m2 := mload(0x40)
    12384
                m3 := mload(0x60)
    12385
                m4 := mload(0x80)
    12386
                m5 := mload(0xa0)
    12387
                m6 := mload(0xc0)
    12388
                // Selector of `log(string,uint256,address,uint256)`.
    12389
                mstore(0x00, 0x4f04fdc6)
    12390
                mstore(0x20, 0x80)
    12391
                mstore(0x40, p1)
    12392
                mstore(0x60, p2)
    12393
                mstore(0x80, p3)
    12394
                writeString(0xa0, p0)
    12395
            }
    12396
            _sendLogPayload(0x1c, 0xc4);
    12397
            /// @solidity memory-safe-assembly
    12398
            assembly {
    12399
                mstore(0x00, m0)
    12400
                mstore(0x20, m1)
    12401
                mstore(0x40, m2)
    12402
                mstore(0x60, m3)
    12403
                mstore(0x80, m4)
    12404
                mstore(0xa0, m5)
    12405
                mstore(0xc0, m6)
    12406
            }
    12407
        }
    12408
    12409
        function log(bytes32 p0, uint256 p1, address p2, bytes32 p3) internal pure {
    12410
            bytes32 m0;
    12411
            bytes32 m1;
    12412
            bytes32 m2;
    12413
            bytes32 m3;
    12414
            bytes32 m4;
    12415
            bytes32 m5;
    12416
            bytes32 m6;
    12417
            bytes32 m7;
    12418
            bytes32 m8;
    12419
            /// @solidity memory-safe-assembly
    12420
            assembly {
    12421
                function writeString(pos, w) {
    12422
                    let length := 0
    12423
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    12424
                    mstore(pos, length)
    12425
                    let shift := sub(256, shl(3, length))
    12426
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    12427
                }
    12428
                m0 := mload(0x00)
    12429
                m1 := mload(0x20)
    12430
                m2 := mload(0x40)
    12431
                m3 := mload(0x60)
    12432
                m4 := mload(0x80)
    12433
                m5 := mload(0xa0)
    12434
                m6 := mload(0xc0)
    12435
                m7 := mload(0xe0)
    12436
                m8 := mload(0x100)
    12437
                // Selector of `log(string,uint256,address,string)`.
    12438
                mstore(0x00, 0x9ffb2f93)
    12439
                mstore(0x20, 0x80)
    12440
                mstore(0x40, p1)
    12441
                mstore(0x60, p2)
    12442
                mstore(0x80, 0xc0)
    12443
                writeString(0xa0, p0)
    12444
                writeString(0xe0, p3)
    12445
            }
    12446
            _sendLogPayload(0x1c, 0x104);
    12447
            /// @solidity memory-safe-assembly
    12448
            assembly {
    12449
                mstore(0x00, m0)
    12450
                mstore(0x20, m1)
    12451
                mstore(0x40, m2)
    12452
                mstore(0x60, m3)
    12453
                mstore(0x80, m4)
    12454
                mstore(0xa0, m5)
    12455
                mstore(0xc0, m6)
    12456
                mstore(0xe0, m7)
    12457
                mstore(0x100, m8)
    12458
            }
    12459
        }
    12460
    12461
        function log(bytes32 p0, uint256 p1, bool p2, address p3) internal pure {
    12462
            bytes32 m0;
    12463
            bytes32 m1;
    12464
            bytes32 m2;
    12465
            bytes32 m3;
    12466
            bytes32 m4;
    12467
            bytes32 m5;
    12468
            bytes32 m6;
    12469
            /// @solidity memory-safe-assembly
    12470
            assembly {
    12471
                function writeString(pos, w) {
    12472
                    let length := 0
    12473
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    12474
                    mstore(pos, length)
    12475
                    let shift := sub(256, shl(3, length))
    12476
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    12477
                }
    12478
                m0 := mload(0x00)
    12479
                m1 := mload(0x20)
    12480
                m2 := mload(0x40)
    12481
                m3 := mload(0x60)
    12482
                m4 := mload(0x80)
    12483
                m5 := mload(0xa0)
    12484
                m6 := mload(0xc0)
    12485
                // Selector of `log(string,uint256,bool,address)`.
    12486
                mstore(0x00, 0xe0e95b98)
    12487
                mstore(0x20, 0x80)
    12488
                mstore(0x40, p1)
    12489
                mstore(0x60, p2)
    12490
                mstore(0x80, p3)
    12491
                writeString(0xa0, p0)
    12492
            }
    12493
            _sendLogPayload(0x1c, 0xc4);
    12494
            /// @solidity memory-safe-assembly
    12495
            assembly {
    12496
                mstore(0x00, m0)
    12497
                mstore(0x20, m1)
    12498
                mstore(0x40, m2)
    12499
                mstore(0x60, m3)
    12500
                mstore(0x80, m4)
    12501
                mstore(0xa0, m5)
    12502
                mstore(0xc0, m6)
    12503
            }
    12504
        }
    12505
    12506
        function log(bytes32 p0, uint256 p1, bool p2, bool p3) internal pure {
    12507
            bytes32 m0;
    12508
            bytes32 m1;
    12509
            bytes32 m2;
    12510
            bytes32 m3;
    12511
            bytes32 m4;
    12512
            bytes32 m5;
    12513
            bytes32 m6;
    12514
            /// @solidity memory-safe-assembly
    12515
            assembly {
    12516
                function writeString(pos, w) {
    12517
                    let length := 0
    12518
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    12519
                    mstore(pos, length)
    12520
                    let shift := sub(256, shl(3, length))
    12521
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    12522
                }
    12523
                m0 := mload(0x00)
    12524
                m1 := mload(0x20)
    12525
                m2 := mload(0x40)
    12526
                m3 := mload(0x60)
    12527
                m4 := mload(0x80)
    12528
                m5 := mload(0xa0)
    12529
                m6 := mload(0xc0)
    12530
                // Selector of `log(string,uint256,bool,bool)`.
    12531
                mstore(0x00, 0x354c36d6)
    12532
                mstore(0x20, 0x80)
    12533
                mstore(0x40, p1)
    12534
                mstore(0x60, p2)
    12535
                mstore(0x80, p3)
    12536
                writeString(0xa0, p0)
    12537
            }
    12538
            _sendLogPayload(0x1c, 0xc4);
    12539
            /// @solidity memory-safe-assembly
    12540
            assembly {
    12541
                mstore(0x00, m0)
    12542
                mstore(0x20, m1)
    12543
                mstore(0x40, m2)
    12544
                mstore(0x60, m3)
    12545
                mstore(0x80, m4)
    12546
                mstore(0xa0, m5)
    12547
                mstore(0xc0, m6)
    12548
            }
    12549
        }
    12550
    12551
        function log(bytes32 p0, uint256 p1, bool p2, uint256 p3) internal pure {
    12552
            bytes32 m0;
    12553
            bytes32 m1;
    12554
            bytes32 m2;
    12555
            bytes32 m3;
    12556
            bytes32 m4;
    12557
            bytes32 m5;
    12558
            bytes32 m6;
    12559
            /// @solidity memory-safe-assembly
    12560
            assembly {
    12561
                function writeString(pos, w) {
    12562
                    let length := 0
    12563
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    12564
                    mstore(pos, length)
    12565
                    let shift := sub(256, shl(3, length))
    12566
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    12567
                }
    12568
                m0 := mload(0x00)
    12569
                m1 := mload(0x20)
    12570
                m2 := mload(0x40)
    12571
                m3 := mload(0x60)
    12572
                m4 := mload(0x80)
    12573
                m5 := mload(0xa0)
    12574
                m6 := mload(0xc0)
    12575
                // Selector of `log(string,uint256,bool,uint256)`.
    12576
                mstore(0x00, 0xe41b6f6f)
    12577
                mstore(0x20, 0x80)
    12578
                mstore(0x40, p1)
    12579
                mstore(0x60, p2)
    12580
                mstore(0x80, p3)
    12581
                writeString(0xa0, p0)
    12582
            }
    12583
            _sendLogPayload(0x1c, 0xc4);
    12584
            /// @solidity memory-safe-assembly
    12585
            assembly {
    12586
                mstore(0x00, m0)
    12587
                mstore(0x20, m1)
    12588
                mstore(0x40, m2)
    12589
                mstore(0x60, m3)
    12590
                mstore(0x80, m4)
    12591
                mstore(0xa0, m5)
    12592
                mstore(0xc0, m6)
    12593
            }
    12594
        }
    12595
    12596
        function log(bytes32 p0, uint256 p1, bool p2, bytes32 p3) internal pure {
    12597
            bytes32 m0;
    12598
            bytes32 m1;
    12599
            bytes32 m2;
    12600
            bytes32 m3;
    12601
            bytes32 m4;
    12602
            bytes32 m5;
    12603
            bytes32 m6;
    12604
            bytes32 m7;
    12605
            bytes32 m8;
    12606
            /// @solidity memory-safe-assembly
    12607
            assembly {
    12608
                function writeString(pos, w) {
    12609
                    let length := 0
    12610
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    12611
                    mstore(pos, length)
    12612
                    let shift := sub(256, shl(3, length))
    12613
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    12614
                }
    12615
                m0 := mload(0x00)
    12616
                m1 := mload(0x20)
    12617
                m2 := mload(0x40)
    12618
                m3 := mload(0x60)
    12619
                m4 := mload(0x80)
    12620
                m5 := mload(0xa0)
    12621
                m6 := mload(0xc0)
    12622
                m7 := mload(0xe0)
    12623
                m8 := mload(0x100)
    12624
                // Selector of `log(string,uint256,bool,string)`.
    12625
                mstore(0x00, 0xabf73a98)
    12626
                mstore(0x20, 0x80)
    12627
                mstore(0x40, p1)
    12628
                mstore(0x60, p2)
    12629
                mstore(0x80, 0xc0)
    12630
                writeString(0xa0, p0)
    12631
                writeString(0xe0, p3)
    12632
            }
    12633
            _sendLogPayload(0x1c, 0x104);
    12634
            /// @solidity memory-safe-assembly
    12635
            assembly {
    12636
                mstore(0x00, m0)
    12637
                mstore(0x20, m1)
    12638
                mstore(0x40, m2)
    12639
                mstore(0x60, m3)
    12640
                mstore(0x80, m4)
    12641
                mstore(0xa0, m5)
    12642
                mstore(0xc0, m6)
    12643
                mstore(0xe0, m7)
    12644
                mstore(0x100, m8)
    12645
            }
    12646
        }
    12647
    12648
        function log(bytes32 p0, uint256 p1, uint256 p2, address p3) internal pure {
    12649
            bytes32 m0;
    12650
            bytes32 m1;
    12651
            bytes32 m2;
    12652
            bytes32 m3;
    12653
            bytes32 m4;
    12654
            bytes32 m5;
    12655
            bytes32 m6;
    12656
            /// @solidity memory-safe-assembly
    12657
            assembly {
    12658
                function writeString(pos, w) {
    12659
                    let length := 0
    12660
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    12661
                    mstore(pos, length)
    12662
                    let shift := sub(256, shl(3, length))
    12663
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    12664
                }
    12665
                m0 := mload(0x00)
    12666
                m1 := mload(0x20)
    12667
                m2 := mload(0x40)
    12668
                m3 := mload(0x60)
    12669
                m4 := mload(0x80)
    12670
                m5 := mload(0xa0)
    12671
                m6 := mload(0xc0)
    12672
                // Selector of `log(string,uint256,uint256,address)`.
    12673
                mstore(0x00, 0xe21de278)
    12674
                mstore(0x20, 0x80)
    12675
                mstore(0x40, p1)
    12676
                mstore(0x60, p2)
    12677
                mstore(0x80, p3)
    12678
                writeString(0xa0, p0)
    12679
            }
    12680
            _sendLogPayload(0x1c, 0xc4);
    12681
            /// @solidity memory-safe-assembly
    12682
            assembly {
    12683
                mstore(0x00, m0)
    12684
                mstore(0x20, m1)
    12685
                mstore(0x40, m2)
    12686
                mstore(0x60, m3)
    12687
                mstore(0x80, m4)
    12688
                mstore(0xa0, m5)
    12689
                mstore(0xc0, m6)
    12690
            }
    12691
        }
    12692
    12693
        function log(bytes32 p0, uint256 p1, uint256 p2, bool p3) internal pure {
    12694
            bytes32 m0;
    12695
            bytes32 m1;
    12696
            bytes32 m2;
    12697
            bytes32 m3;
    12698
            bytes32 m4;
    12699
            bytes32 m5;
    12700
            bytes32 m6;
    12701
            /// @solidity memory-safe-assembly
    12702
            assembly {
    12703
                function writeString(pos, w) {
    12704
                    let length := 0
    12705
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    12706
                    mstore(pos, length)
    12707
                    let shift := sub(256, shl(3, length))
    12708
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    12709
                }
    12710
                m0 := mload(0x00)
    12711
                m1 := mload(0x20)
    12712
                m2 := mload(0x40)
    12713
                m3 := mload(0x60)
    12714
                m4 := mload(0x80)
    12715
                m5 := mload(0xa0)
    12716
                m6 := mload(0xc0)
    12717
                // Selector of `log(string,uint256,uint256,bool)`.
    12718
                mstore(0x00, 0x7626db92)
    12719
                mstore(0x20, 0x80)
    12720
                mstore(0x40, p1)
    12721
                mstore(0x60, p2)
    12722
                mstore(0x80, p3)
    12723
                writeString(0xa0, p0)
    12724
            }
    12725
            _sendLogPayload(0x1c, 0xc4);
    12726
            /// @solidity memory-safe-assembly
    12727
            assembly {
    12728
                mstore(0x00, m0)
    12729
                mstore(0x20, m1)
    12730
                mstore(0x40, m2)
    12731
                mstore(0x60, m3)
    12732
                mstore(0x80, m4)
    12733
                mstore(0xa0, m5)
    12734
                mstore(0xc0, m6)
    12735
            }
    12736
        }
    12737
    12738
        function log(bytes32 p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
    12739
            bytes32 m0;
    12740
            bytes32 m1;
    12741
            bytes32 m2;
    12742
            bytes32 m3;
    12743
            bytes32 m4;
    12744
            bytes32 m5;
    12745
            bytes32 m6;
    12746
            /// @solidity memory-safe-assembly
    12747
            assembly {
    12748
                function writeString(pos, w) {
    12749
                    let length := 0
    12750
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    12751
                    mstore(pos, length)
    12752
                    let shift := sub(256, shl(3, length))
    12753
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    12754
                }
    12755
                m0 := mload(0x00)
    12756
                m1 := mload(0x20)
    12757
                m2 := mload(0x40)
    12758
                m3 := mload(0x60)
    12759
                m4 := mload(0x80)
    12760
                m5 := mload(0xa0)
    12761
                m6 := mload(0xc0)
    12762
                // Selector of `log(string,uint256,uint256,uint256)`.
    12763
                mstore(0x00, 0xa7a87853)
    12764
                mstore(0x20, 0x80)
    12765
                mstore(0x40, p1)
    12766
                mstore(0x60, p2)
    12767
                mstore(0x80, p3)
    12768
                writeString(0xa0, p0)
    12769
            }
    12770
            _sendLogPayload(0x1c, 0xc4);
    12771
            /// @solidity memory-safe-assembly
    12772
            assembly {
    12773
                mstore(0x00, m0)
    12774
                mstore(0x20, m1)
    12775
                mstore(0x40, m2)
    12776
                mstore(0x60, m3)
    12777
                mstore(0x80, m4)
    12778
                mstore(0xa0, m5)
    12779
                mstore(0xc0, m6)
    12780
            }
    12781
        }
    12782
    12783
        function log(bytes32 p0, uint256 p1, uint256 p2, bytes32 p3) internal pure {
    12784
            bytes32 m0;
    12785
            bytes32 m1;
    12786
            bytes32 m2;
    12787
            bytes32 m3;
    12788
            bytes32 m4;
    12789
            bytes32 m5;
    12790
            bytes32 m6;
    12791
            bytes32 m7;
    12792
            bytes32 m8;
    12793
            /// @solidity memory-safe-assembly
    12794
            assembly {
    12795
                function writeString(pos, w) {
    12796
                    let length := 0
    12797
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    12798
                    mstore(pos, length)
    12799
                    let shift := sub(256, shl(3, length))
    12800
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    12801
                }
    12802
                m0 := mload(0x00)
    12803
                m1 := mload(0x20)
    12804
                m2 := mload(0x40)
    12805
                m3 := mload(0x60)
    12806
                m4 := mload(0x80)
    12807
                m5 := mload(0xa0)
    12808
                m6 := mload(0xc0)
    12809
                m7 := mload(0xe0)
    12810
                m8 := mload(0x100)
    12811
                // Selector of `log(string,uint256,uint256,string)`.
    12812
                mstore(0x00, 0x854b3496)
    12813
                mstore(0x20, 0x80)
    12814
                mstore(0x40, p1)
    12815
                mstore(0x60, p2)
    12816
                mstore(0x80, 0xc0)
    12817
                writeString(0xa0, p0)
    12818
                writeString(0xe0, p3)
    12819
            }
    12820
            _sendLogPayload(0x1c, 0x104);
    12821
            /// @solidity memory-safe-assembly
    12822
            assembly {
    12823
                mstore(0x00, m0)
    12824
                mstore(0x20, m1)
    12825
                mstore(0x40, m2)
    12826
                mstore(0x60, m3)
    12827
                mstore(0x80, m4)
    12828
                mstore(0xa0, m5)
    12829
                mstore(0xc0, m6)
    12830
                mstore(0xe0, m7)
    12831
                mstore(0x100, m8)
    12832
            }
    12833
        }
    12834
    12835
        function log(bytes32 p0, uint256 p1, bytes32 p2, address p3) internal pure {
    12836
            bytes32 m0;
    12837
            bytes32 m1;
    12838
            bytes32 m2;
    12839
            bytes32 m3;
    12840
            bytes32 m4;
    12841
            bytes32 m5;
    12842
            bytes32 m6;
    12843
            bytes32 m7;
    12844
            bytes32 m8;
    12845
            /// @solidity memory-safe-assembly
    12846
            assembly {
    12847
                function writeString(pos, w) {
    12848
                    let length := 0
    12849
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    12850
                    mstore(pos, length)
    12851
                    let shift := sub(256, shl(3, length))
    12852
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    12853
                }
    12854
                m0 := mload(0x00)
    12855
                m1 := mload(0x20)
    12856
                m2 := mload(0x40)
    12857
                m3 := mload(0x60)
    12858
                m4 := mload(0x80)
    12859
                m5 := mload(0xa0)
    12860
                m6 := mload(0xc0)
    12861
                m7 := mload(0xe0)
    12862
                m8 := mload(0x100)
    12863
                // Selector of `log(string,uint256,string,address)`.
    12864
                mstore(0x00, 0x7c4632a4)
    12865
                mstore(0x20, 0x80)
    12866
                mstore(0x40, p1)
    12867
                mstore(0x60, 0xc0)
    12868
                mstore(0x80, p3)
    12869
                writeString(0xa0, p0)
    12870
                writeString(0xe0, p2)
    12871
            }
    12872
            _sendLogPayload(0x1c, 0x104);
    12873
            /// @solidity memory-safe-assembly
    12874
            assembly {
    12875
                mstore(0x00, m0)
    12876
                mstore(0x20, m1)
    12877
                mstore(0x40, m2)
    12878
                mstore(0x60, m3)
    12879
                mstore(0x80, m4)
    12880
                mstore(0xa0, m5)
    12881
                mstore(0xc0, m6)
    12882
                mstore(0xe0, m7)
    12883
                mstore(0x100, m8)
    12884
            }
    12885
        }
    12886
    12887
        function log(bytes32 p0, uint256 p1, bytes32 p2, bool p3) internal pure {
    12888
            bytes32 m0;
    12889
            bytes32 m1;
    12890
            bytes32 m2;
    12891
            bytes32 m3;
    12892
            bytes32 m4;
    12893
            bytes32 m5;
    12894
            bytes32 m6;
    12895
            bytes32 m7;
    12896
            bytes32 m8;
    12897
            /// @solidity memory-safe-assembly
    12898
            assembly {
    12899
                function writeString(pos, w) {
    12900
                    let length := 0
    12901
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    12902
                    mstore(pos, length)
    12903
                    let shift := sub(256, shl(3, length))
    12904
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    12905
                }
    12906
                m0 := mload(0x00)
    12907
                m1 := mload(0x20)
    12908
                m2 := mload(0x40)
    12909
                m3 := mload(0x60)
    12910
                m4 := mload(0x80)
    12911
                m5 := mload(0xa0)
    12912
                m6 := mload(0xc0)
    12913
                m7 := mload(0xe0)
    12914
                m8 := mload(0x100)
    12915
                // Selector of `log(string,uint256,string,bool)`.
    12916
                mstore(0x00, 0x7d24491d)
    12917
                mstore(0x20, 0x80)
    12918
                mstore(0x40, p1)
    12919
                mstore(0x60, 0xc0)
    12920
                mstore(0x80, p3)
    12921
                writeString(0xa0, p0)
    12922
                writeString(0xe0, p2)
    12923
            }
    12924
            _sendLogPayload(0x1c, 0x104);
    12925
            /// @solidity memory-safe-assembly
    12926
            assembly {
    12927
                mstore(0x00, m0)
    12928
                mstore(0x20, m1)
    12929
                mstore(0x40, m2)
    12930
                mstore(0x60, m3)
    12931
                mstore(0x80, m4)
    12932
                mstore(0xa0, m5)
    12933
                mstore(0xc0, m6)
    12934
                mstore(0xe0, m7)
    12935
                mstore(0x100, m8)
    12936
            }
    12937
        }
    12938
    12939
        function log(bytes32 p0, uint256 p1, bytes32 p2, uint256 p3) internal pure {
    12940
            bytes32 m0;
    12941
            bytes32 m1;
    12942
            bytes32 m2;
    12943
            bytes32 m3;
    12944
            bytes32 m4;
    12945
            bytes32 m5;
    12946
            bytes32 m6;
    12947
            bytes32 m7;
    12948
            bytes32 m8;
    12949
            /// @solidity memory-safe-assembly
    12950
            assembly {
    12951
                function writeString(pos, w) {
    12952
                    let length := 0
    12953
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    12954
                    mstore(pos, length)
    12955
                    let shift := sub(256, shl(3, length))
    12956
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    12957
                }
    12958
                m0 := mload(0x00)
    12959
                m1 := mload(0x20)
    12960
                m2 := mload(0x40)
    12961
                m3 := mload(0x60)
    12962
                m4 := mload(0x80)
    12963
                m5 := mload(0xa0)
    12964
                m6 := mload(0xc0)
    12965
                m7 := mload(0xe0)
    12966
                m8 := mload(0x100)
    12967
                // Selector of `log(string,uint256,string,uint256)`.
    12968
                mstore(0x00, 0xc67ea9d1)
    12969
                mstore(0x20, 0x80)
    12970
                mstore(0x40, p1)
    12971
                mstore(0x60, 0xc0)
    12972
                mstore(0x80, p3)
    12973
                writeString(0xa0, p0)
    12974
                writeString(0xe0, p2)
    12975
            }
    12976
            _sendLogPayload(0x1c, 0x104);
    12977
            /// @solidity memory-safe-assembly
    12978
            assembly {
    12979
                mstore(0x00, m0)
    12980
                mstore(0x20, m1)
    12981
                mstore(0x40, m2)
    12982
                mstore(0x60, m3)
    12983
                mstore(0x80, m4)
    12984
                mstore(0xa0, m5)
    12985
                mstore(0xc0, m6)
    12986
                mstore(0xe0, m7)
    12987
                mstore(0x100, m8)
    12988
            }
    12989
        }
    12990
    12991
        function log(bytes32 p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure {
    12992
            bytes32 m0;
    12993
            bytes32 m1;
    12994
            bytes32 m2;
    12995
            bytes32 m3;
    12996
            bytes32 m4;
    12997
            bytes32 m5;
    12998
            bytes32 m6;
    12999
            bytes32 m7;
    13000
            bytes32 m8;
    13001
            bytes32 m9;
    13002
            bytes32 m10;
    13003
            /// @solidity memory-safe-assembly
    13004
            assembly {
    13005
                function writeString(pos, w) {
    13006
                    let length := 0
    13007
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    13008
                    mstore(pos, length)
    13009
                    let shift := sub(256, shl(3, length))
    13010
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    13011
                }
    13012
                m0 := mload(0x00)
    13013
                m1 := mload(0x20)
    13014
                m2 := mload(0x40)
    13015
                m3 := mload(0x60)
    13016
                m4 := mload(0x80)
    13017
                m5 := mload(0xa0)
    13018
                m6 := mload(0xc0)
    13019
                m7 := mload(0xe0)
    13020
                m8 := mload(0x100)
    13021
                m9 := mload(0x120)
    13022
                m10 := mload(0x140)
    13023
                // Selector of `log(string,uint256,string,string)`.
    13024
                mstore(0x00, 0x5ab84e1f)
    13025
                mstore(0x20, 0x80)
    13026
                mstore(0x40, p1)
    13027
                mstore(0x60, 0xc0)
    13028
                mstore(0x80, 0x100)
    13029
                writeString(0xa0, p0)
    13030
                writeString(0xe0, p2)
    13031
                writeString(0x120, p3)
    13032
            }
    13033
            _sendLogPayload(0x1c, 0x144);
    13034
            /// @solidity memory-safe-assembly
    13035
            assembly {
    13036
                mstore(0x00, m0)
    13037
                mstore(0x20, m1)
    13038
                mstore(0x40, m2)
    13039
                mstore(0x60, m3)
    13040
                mstore(0x80, m4)
    13041
                mstore(0xa0, m5)
    13042
                mstore(0xc0, m6)
    13043
                mstore(0xe0, m7)
    13044
                mstore(0x100, m8)
    13045
                mstore(0x120, m9)
    13046
                mstore(0x140, m10)
    13047
            }
    13048
        }
    13049
    13050
        function log(bytes32 p0, bytes32 p1, address p2, address p3) internal pure {
    13051
            bytes32 m0;
    13052
            bytes32 m1;
    13053
            bytes32 m2;
    13054
            bytes32 m3;
    13055
            bytes32 m4;
    13056
            bytes32 m5;
    13057
            bytes32 m6;
    13058
            bytes32 m7;
    13059
            bytes32 m8;
    13060
            /// @solidity memory-safe-assembly
    13061
            assembly {
    13062
                function writeString(pos, w) {
    13063
                    let length := 0
    13064
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    13065
                    mstore(pos, length)
    13066
                    let shift := sub(256, shl(3, length))
    13067
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    13068
                }
    13069
                m0 := mload(0x00)
    13070
                m1 := mload(0x20)
    13071
                m2 := mload(0x40)
    13072
                m3 := mload(0x60)
    13073
                m4 := mload(0x80)
    13074
                m5 := mload(0xa0)
    13075
                m6 := mload(0xc0)
    13076
                m7 := mload(0xe0)
    13077
                m8 := mload(0x100)
    13078
                // Selector of `log(string,string,address,address)`.
    13079
                mstore(0x00, 0x439c7bef)
    13080
                mstore(0x20, 0x80)
    13081
                mstore(0x40, 0xc0)
    13082
                mstore(0x60, p2)
    13083
                mstore(0x80, p3)
    13084
                writeString(0xa0, p0)
    13085
                writeString(0xe0, p1)
    13086
            }
    13087
            _sendLogPayload(0x1c, 0x104);
    13088
            /// @solidity memory-safe-assembly
    13089
            assembly {
    13090
                mstore(0x00, m0)
    13091
                mstore(0x20, m1)
    13092
                mstore(0x40, m2)
    13093
                mstore(0x60, m3)
    13094
                mstore(0x80, m4)
    13095
                mstore(0xa0, m5)
    13096
                mstore(0xc0, m6)
    13097
                mstore(0xe0, m7)
    13098
                mstore(0x100, m8)
    13099
            }
    13100
        }
    13101
    13102
        function log(bytes32 p0, bytes32 p1, address p2, bool p3) internal pure {
    13103
            bytes32 m0;
    13104
            bytes32 m1;
    13105
            bytes32 m2;
    13106
            bytes32 m3;
    13107
            bytes32 m4;
    13108
            bytes32 m5;
    13109
            bytes32 m6;
    13110
            bytes32 m7;
    13111
            bytes32 m8;
    13112
            /// @solidity memory-safe-assembly
    13113
            assembly {
    13114
                function writeString(pos, w) {
    13115
                    let length := 0
    13116
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    13117
                    mstore(pos, length)
    13118
                    let shift := sub(256, shl(3, length))
    13119
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    13120
                }
    13121
                m0 := mload(0x00)
    13122
                m1 := mload(0x20)
    13123
                m2 := mload(0x40)
    13124
                m3 := mload(0x60)
    13125
                m4 := mload(0x80)
    13126
                m5 := mload(0xa0)
    13127
                m6 := mload(0xc0)
    13128
                m7 := mload(0xe0)
    13129
                m8 := mload(0x100)
    13130
                // Selector of `log(string,string,address,bool)`.
    13131
                mstore(0x00, 0x5ccd4e37)
    13132
                mstore(0x20, 0x80)
    13133
                mstore(0x40, 0xc0)
    13134
                mstore(0x60, p2)
    13135
                mstore(0x80, p3)
    13136
                writeString(0xa0, p0)
    13137
                writeString(0xe0, p1)
    13138
            }
    13139
            _sendLogPayload(0x1c, 0x104);
    13140
            /// @solidity memory-safe-assembly
    13141
            assembly {
    13142
                mstore(0x00, m0)
    13143
                mstore(0x20, m1)
    13144
                mstore(0x40, m2)
    13145
                mstore(0x60, m3)
    13146
                mstore(0x80, m4)
    13147
                mstore(0xa0, m5)
    13148
                mstore(0xc0, m6)
    13149
                mstore(0xe0, m7)
    13150
                mstore(0x100, m8)
    13151
            }
    13152
        }
    13153
    13154
        function log(bytes32 p0, bytes32 p1, address p2, uint256 p3) internal pure {
    13155
            bytes32 m0;
    13156
            bytes32 m1;
    13157
            bytes32 m2;
    13158
            bytes32 m3;
    13159
            bytes32 m4;
    13160
            bytes32 m5;
    13161
            bytes32 m6;
    13162
            bytes32 m7;
    13163
            bytes32 m8;
    13164
            /// @solidity memory-safe-assembly
    13165
            assembly {
    13166
                function writeString(pos, w) {
    13167
                    let length := 0
    13168
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    13169
                    mstore(pos, length)
    13170
                    let shift := sub(256, shl(3, length))
    13171
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    13172
                }
    13173
                m0 := mload(0x00)
    13174
                m1 := mload(0x20)
    13175
                m2 := mload(0x40)
    13176
                m3 := mload(0x60)
    13177
                m4 := mload(0x80)
    13178
                m5 := mload(0xa0)
    13179
                m6 := mload(0xc0)
    13180
                m7 := mload(0xe0)
    13181
                m8 := mload(0x100)
    13182
                // Selector of `log(string,string,address,uint256)`.
    13183
                mstore(0x00, 0x7cc3c607)
    13184
                mstore(0x20, 0x80)
    13185
                mstore(0x40, 0xc0)
    13186
                mstore(0x60, p2)
    13187
                mstore(0x80, p3)
    13188
                writeString(0xa0, p0)
    13189
                writeString(0xe0, p1)
    13190
            }
    13191
            _sendLogPayload(0x1c, 0x104);
    13192
            /// @solidity memory-safe-assembly
    13193
            assembly {
    13194
                mstore(0x00, m0)
    13195
                mstore(0x20, m1)
    13196
                mstore(0x40, m2)
    13197
                mstore(0x60, m3)
    13198
                mstore(0x80, m4)
    13199
                mstore(0xa0, m5)
    13200
                mstore(0xc0, m6)
    13201
                mstore(0xe0, m7)
    13202
                mstore(0x100, m8)
    13203
            }
    13204
        }
    13205
    13206
        function log(bytes32 p0, bytes32 p1, address p2, bytes32 p3) internal pure {
    13207
            bytes32 m0;
    13208
            bytes32 m1;
    13209
            bytes32 m2;
    13210
            bytes32 m3;
    13211
            bytes32 m4;
    13212
            bytes32 m5;
    13213
            bytes32 m6;
    13214
            bytes32 m7;
    13215
            bytes32 m8;
    13216
            bytes32 m9;
    13217
            bytes32 m10;
    13218
            /// @solidity memory-safe-assembly
    13219
            assembly {
    13220
                function writeString(pos, w) {
    13221
                    let length := 0
    13222
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    13223
                    mstore(pos, length)
    13224
                    let shift := sub(256, shl(3, length))
    13225
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    13226
                }
    13227
                m0 := mload(0x00)
    13228
                m1 := mload(0x20)
    13229
                m2 := mload(0x40)
    13230
                m3 := mload(0x60)
    13231
                m4 := mload(0x80)
    13232
                m5 := mload(0xa0)
    13233
                m6 := mload(0xc0)
    13234
                m7 := mload(0xe0)
    13235
                m8 := mload(0x100)
    13236
                m9 := mload(0x120)
    13237
                m10 := mload(0x140)
    13238
                // Selector of `log(string,string,address,string)`.
    13239
                mstore(0x00, 0xeb1bff80)
    13240
                mstore(0x20, 0x80)
    13241
                mstore(0x40, 0xc0)
    13242
                mstore(0x60, p2)
    13243
                mstore(0x80, 0x100)
    13244
                writeString(0xa0, p0)
    13245
                writeString(0xe0, p1)
    13246
                writeString(0x120, p3)
    13247
            }
    13248
            _sendLogPayload(0x1c, 0x144);
    13249
            /// @solidity memory-safe-assembly
    13250
            assembly {
    13251
                mstore(0x00, m0)
    13252
                mstore(0x20, m1)
    13253
                mstore(0x40, m2)
    13254
                mstore(0x60, m3)
    13255
                mstore(0x80, m4)
    13256
                mstore(0xa0, m5)
    13257
                mstore(0xc0, m6)
    13258
                mstore(0xe0, m7)
    13259
                mstore(0x100, m8)
    13260
                mstore(0x120, m9)
    13261
                mstore(0x140, m10)
    13262
            }
    13263
        }
    13264
    13265
        function log(bytes32 p0, bytes32 p1, bool p2, address p3) internal pure {
    13266
            bytes32 m0;
    13267
            bytes32 m1;
    13268
            bytes32 m2;
    13269
            bytes32 m3;
    13270
            bytes32 m4;
    13271
            bytes32 m5;
    13272
            bytes32 m6;
    13273
            bytes32 m7;
    13274
            bytes32 m8;
    13275
            /// @solidity memory-safe-assembly
    13276
            assembly {
    13277
                function writeString(pos, w) {
    13278
                    let length := 0
    13279
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    13280
                    mstore(pos, length)
    13281
                    let shift := sub(256, shl(3, length))
    13282
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    13283
                }
    13284
                m0 := mload(0x00)
    13285
                m1 := mload(0x20)
    13286
                m2 := mload(0x40)
    13287
                m3 := mload(0x60)
    13288
                m4 := mload(0x80)
    13289
                m5 := mload(0xa0)
    13290
                m6 := mload(0xc0)
    13291
                m7 := mload(0xe0)
    13292
                m8 := mload(0x100)
    13293
                // Selector of `log(string,string,bool,address)`.
    13294
                mstore(0x00, 0xc371c7db)
    13295
                mstore(0x20, 0x80)
    13296
                mstore(0x40, 0xc0)
    13297
                mstore(0x60, p2)
    13298
                mstore(0x80, p3)
    13299
                writeString(0xa0, p0)
    13300
                writeString(0xe0, p1)
    13301
            }
    13302
            _sendLogPayload(0x1c, 0x104);
    13303
            /// @solidity memory-safe-assembly
    13304
            assembly {
    13305
                mstore(0x00, m0)
    13306
                mstore(0x20, m1)
    13307
                mstore(0x40, m2)
    13308
                mstore(0x60, m3)
    13309
                mstore(0x80, m4)
    13310
                mstore(0xa0, m5)
    13311
                mstore(0xc0, m6)
    13312
                mstore(0xe0, m7)
    13313
                mstore(0x100, m8)
    13314
            }
    13315
        }
    13316
    13317
        function log(bytes32 p0, bytes32 p1, bool p2, bool p3) internal pure {
    13318
            bytes32 m0;
    13319
            bytes32 m1;
    13320
            bytes32 m2;
    13321
            bytes32 m3;
    13322
            bytes32 m4;
    13323
            bytes32 m5;
    13324
            bytes32 m6;
    13325
            bytes32 m7;
    13326
            bytes32 m8;
    13327
            /// @solidity memory-safe-assembly
    13328
            assembly {
    13329
                function writeString(pos, w) {
    13330
                    let length := 0
    13331
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    13332
                    mstore(pos, length)
    13333
                    let shift := sub(256, shl(3, length))
    13334
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    13335
                }
    13336
                m0 := mload(0x00)
    13337
                m1 := mload(0x20)
    13338
                m2 := mload(0x40)
    13339
                m3 := mload(0x60)
    13340
                m4 := mload(0x80)
    13341
                m5 := mload(0xa0)
    13342
                m6 := mload(0xc0)
    13343
                m7 := mload(0xe0)
    13344
                m8 := mload(0x100)
    13345
                // Selector of `log(string,string,bool,bool)`.
    13346
                mstore(0x00, 0x40785869)
    13347
                mstore(0x20, 0x80)
    13348
                mstore(0x40, 0xc0)
    13349
                mstore(0x60, p2)
    13350
                mstore(0x80, p3)
    13351
                writeString(0xa0, p0)
    13352
                writeString(0xe0, p1)
    13353
            }
    13354
            _sendLogPayload(0x1c, 0x104);
    13355
            /// @solidity memory-safe-assembly
    13356
            assembly {
    13357
                mstore(0x00, m0)
    13358
                mstore(0x20, m1)
    13359
                mstore(0x40, m2)
    13360
                mstore(0x60, m3)
    13361
                mstore(0x80, m4)
    13362
                mstore(0xa0, m5)
    13363
                mstore(0xc0, m6)
    13364
                mstore(0xe0, m7)
    13365
                mstore(0x100, m8)
    13366
            }
    13367
        }
    13368
    13369
        function log(bytes32 p0, bytes32 p1, bool p2, uint256 p3) internal pure {
    13370
            bytes32 m0;
    13371
            bytes32 m1;
    13372
            bytes32 m2;
    13373
            bytes32 m3;
    13374
            bytes32 m4;
    13375
            bytes32 m5;
    13376
            bytes32 m6;
    13377
            bytes32 m7;
    13378
            bytes32 m8;
    13379
            /// @solidity memory-safe-assembly
    13380
            assembly {
    13381
                function writeString(pos, w) {
    13382
                    let length := 0
    13383
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    13384
                    mstore(pos, length)
    13385
                    let shift := sub(256, shl(3, length))
    13386
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    13387
                }
    13388
                m0 := mload(0x00)
    13389
                m1 := mload(0x20)
    13390
                m2 := mload(0x40)
    13391
                m3 := mload(0x60)
    13392
                m4 := mload(0x80)
    13393
                m5 := mload(0xa0)
    13394
                m6 := mload(0xc0)
    13395
                m7 := mload(0xe0)
    13396
                m8 := mload(0x100)
    13397
                // Selector of `log(string,string,bool,uint256)`.
    13398
                mstore(0x00, 0xd6aefad2)
    13399
                mstore(0x20, 0x80)
    13400
                mstore(0x40, 0xc0)
    13401
                mstore(0x60, p2)
    13402
                mstore(0x80, p3)
    13403
                writeString(0xa0, p0)
    13404
                writeString(0xe0, p1)
    13405
            }
    13406
            _sendLogPayload(0x1c, 0x104);
    13407
            /// @solidity memory-safe-assembly
    13408
            assembly {
    13409
                mstore(0x00, m0)
    13410
                mstore(0x20, m1)
    13411
                mstore(0x40, m2)
    13412
                mstore(0x60, m3)
    13413
                mstore(0x80, m4)
    13414
                mstore(0xa0, m5)
    13415
                mstore(0xc0, m6)
    13416
                mstore(0xe0, m7)
    13417
                mstore(0x100, m8)
    13418
            }
    13419
        }
    13420
    13421
        function log(bytes32 p0, bytes32 p1, bool p2, bytes32 p3) internal pure {
    13422
            bytes32 m0;
    13423
            bytes32 m1;
    13424
            bytes32 m2;
    13425
            bytes32 m3;
    13426
            bytes32 m4;
    13427
            bytes32 m5;
    13428
            bytes32 m6;
    13429
            bytes32 m7;
    13430
            bytes32 m8;
    13431
            bytes32 m9;
    13432
            bytes32 m10;
    13433
            /// @solidity memory-safe-assembly
    13434
            assembly {
    13435
                function writeString(pos, w) {
    13436
                    let length := 0
    13437
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    13438
                    mstore(pos, length)
    13439
                    let shift := sub(256, shl(3, length))
    13440
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    13441
                }
    13442
                m0 := mload(0x00)
    13443
                m1 := mload(0x20)
    13444
                m2 := mload(0x40)
    13445
                m3 := mload(0x60)
    13446
                m4 := mload(0x80)
    13447
                m5 := mload(0xa0)
    13448
                m6 := mload(0xc0)
    13449
                m7 := mload(0xe0)
    13450
                m8 := mload(0x100)
    13451
                m9 := mload(0x120)
    13452
                m10 := mload(0x140)
    13453
                // Selector of `log(string,string,bool,string)`.
    13454
                mstore(0x00, 0x5e84b0ea)
    13455
                mstore(0x20, 0x80)
    13456
                mstore(0x40, 0xc0)
    13457
                mstore(0x60, p2)
    13458
                mstore(0x80, 0x100)
    13459
                writeString(0xa0, p0)
    13460
                writeString(0xe0, p1)
    13461
                writeString(0x120, p3)
    13462
            }
    13463
            _sendLogPayload(0x1c, 0x144);
    13464
            /// @solidity memory-safe-assembly
    13465
            assembly {
    13466
                mstore(0x00, m0)
    13467
                mstore(0x20, m1)
    13468
                mstore(0x40, m2)
    13469
                mstore(0x60, m3)
    13470
                mstore(0x80, m4)
    13471
                mstore(0xa0, m5)
    13472
                mstore(0xc0, m6)
    13473
                mstore(0xe0, m7)
    13474
                mstore(0x100, m8)
    13475
                mstore(0x120, m9)
    13476
                mstore(0x140, m10)
    13477
            }
    13478
        }
    13479
    13480
        function log(bytes32 p0, bytes32 p1, uint256 p2, address p3) internal pure {
    13481
            bytes32 m0;
    13482
            bytes32 m1;
    13483
            bytes32 m2;
    13484
            bytes32 m3;
    13485
            bytes32 m4;
    13486
            bytes32 m5;
    13487
            bytes32 m6;
    13488
            bytes32 m7;
    13489
            bytes32 m8;
    13490
            /// @solidity memory-safe-assembly
    13491
            assembly {
    13492
                function writeString(pos, w) {
    13493
                    let length := 0
    13494
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    13495
                    mstore(pos, length)
    13496
                    let shift := sub(256, shl(3, length))
    13497
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    13498
                }
    13499
                m0 := mload(0x00)
    13500
                m1 := mload(0x20)
    13501
                m2 := mload(0x40)
    13502
                m3 := mload(0x60)
    13503
                m4 := mload(0x80)
    13504
                m5 := mload(0xa0)
    13505
                m6 := mload(0xc0)
    13506
                m7 := mload(0xe0)
    13507
                m8 := mload(0x100)
    13508
                // Selector of `log(string,string,uint256,address)`.
    13509
                mstore(0x00, 0x1023f7b2)
    13510
                mstore(0x20, 0x80)
    13511
                mstore(0x40, 0xc0)
    13512
                mstore(0x60, p2)
    13513
                mstore(0x80, p3)
    13514
                writeString(0xa0, p0)
    13515
                writeString(0xe0, p1)
    13516
            }
    13517
            _sendLogPayload(0x1c, 0x104);
    13518
            /// @solidity memory-safe-assembly
    13519
            assembly {
    13520
                mstore(0x00, m0)
    13521
                mstore(0x20, m1)
    13522
                mstore(0x40, m2)
    13523
                mstore(0x60, m3)
    13524
                mstore(0x80, m4)
    13525
                mstore(0xa0, m5)
    13526
                mstore(0xc0, m6)
    13527
                mstore(0xe0, m7)
    13528
                mstore(0x100, m8)
    13529
            }
    13530
        }
    13531
    13532
        function log(bytes32 p0, bytes32 p1, uint256 p2, bool p3) internal pure {
    13533
            bytes32 m0;
    13534
            bytes32 m1;
    13535
            bytes32 m2;
    13536
            bytes32 m3;
    13537
            bytes32 m4;
    13538
            bytes32 m5;
    13539
            bytes32 m6;
    13540
            bytes32 m7;
    13541
            bytes32 m8;
    13542
            /// @solidity memory-safe-assembly
    13543
            assembly {
    13544
                function writeString(pos, w) {
    13545
                    let length := 0
    13546
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    13547
                    mstore(pos, length)
    13548
                    let shift := sub(256, shl(3, length))
    13549
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    13550
                }
    13551
                m0 := mload(0x00)
    13552
                m1 := mload(0x20)
    13553
                m2 := mload(0x40)
    13554
                m3 := mload(0x60)
    13555
                m4 := mload(0x80)
    13556
                m5 := mload(0xa0)
    13557
                m6 := mload(0xc0)
    13558
                m7 := mload(0xe0)
    13559
                m8 := mload(0x100)
    13560
                // Selector of `log(string,string,uint256,bool)`.
    13561
                mstore(0x00, 0xc3a8a654)
    13562
                mstore(0x20, 0x80)
    13563
                mstore(0x40, 0xc0)
    13564
                mstore(0x60, p2)
    13565
                mstore(0x80, p3)
    13566
                writeString(0xa0, p0)
    13567
                writeString(0xe0, p1)
    13568
            }
    13569
            _sendLogPayload(0x1c, 0x104);
    13570
            /// @solidity memory-safe-assembly
    13571
            assembly {
    13572
                mstore(0x00, m0)
    13573
                mstore(0x20, m1)
    13574
                mstore(0x40, m2)
    13575
                mstore(0x60, m3)
    13576
                mstore(0x80, m4)
    13577
                mstore(0xa0, m5)
    13578
                mstore(0xc0, m6)
    13579
                mstore(0xe0, m7)
    13580
                mstore(0x100, m8)
    13581
            }
    13582
        }
    13583
    13584
        function log(bytes32 p0, bytes32 p1, uint256 p2, uint256 p3) internal pure {
    13585
            bytes32 m0;
    13586
            bytes32 m1;
    13587
            bytes32 m2;
    13588
            bytes32 m3;
    13589
            bytes32 m4;
    13590
            bytes32 m5;
    13591
            bytes32 m6;
    13592
            bytes32 m7;
    13593
            bytes32 m8;
    13594
            /// @solidity memory-safe-assembly
    13595
            assembly {
    13596
                function writeString(pos, w) {
    13597
                    let length := 0
    13598
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    13599
                    mstore(pos, length)
    13600
                    let shift := sub(256, shl(3, length))
    13601
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    13602
                }
    13603
                m0 := mload(0x00)
    13604
                m1 := mload(0x20)
    13605
                m2 := mload(0x40)
    13606
                m3 := mload(0x60)
    13607
                m4 := mload(0x80)
    13608
                m5 := mload(0xa0)
    13609
                m6 := mload(0xc0)
    13610
                m7 := mload(0xe0)
    13611
                m8 := mload(0x100)
    13612
                // Selector of `log(string,string,uint256,uint256)`.
    13613
                mstore(0x00, 0xf45d7d2c)
    13614
                mstore(0x20, 0x80)
    13615
                mstore(0x40, 0xc0)
    13616
                mstore(0x60, p2)
    13617
                mstore(0x80, p3)
    13618
                writeString(0xa0, p0)
    13619
                writeString(0xe0, p1)
    13620
            }
    13621
            _sendLogPayload(0x1c, 0x104);
    13622
            /// @solidity memory-safe-assembly
    13623
            assembly {
    13624
                mstore(0x00, m0)
    13625
                mstore(0x20, m1)
    13626
                mstore(0x40, m2)
    13627
                mstore(0x60, m3)
    13628
                mstore(0x80, m4)
    13629
                mstore(0xa0, m5)
    13630
                mstore(0xc0, m6)
    13631
                mstore(0xe0, m7)
    13632
                mstore(0x100, m8)
    13633
            }
    13634
        }
    13635
    13636
        function log(bytes32 p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure {
    13637
            bytes32 m0;
    13638
            bytes32 m1;
    13639
            bytes32 m2;
    13640
            bytes32 m3;
    13641
            bytes32 m4;
    13642
            bytes32 m5;
    13643
            bytes32 m6;
    13644
            bytes32 m7;
    13645
            bytes32 m8;
    13646
            bytes32 m9;
    13647
            bytes32 m10;
    13648
            /// @solidity memory-safe-assembly
    13649
            assembly {
    13650
                function writeString(pos, w) {
    13651
                    let length := 0
    13652
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    13653
                    mstore(pos, length)
    13654
                    let shift := sub(256, shl(3, length))
    13655
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    13656
                }
    13657
                m0 := mload(0x00)
    13658
                m1 := mload(0x20)
    13659
                m2 := mload(0x40)
    13660
                m3 := mload(0x60)
    13661
                m4 := mload(0x80)
    13662
                m5 := mload(0xa0)
    13663
                m6 := mload(0xc0)
    13664
                m7 := mload(0xe0)
    13665
                m8 := mload(0x100)
    13666
                m9 := mload(0x120)
    13667
                m10 := mload(0x140)
    13668
                // Selector of `log(string,string,uint256,string)`.
    13669
                mstore(0x00, 0x5d1a971a)
    13670
                mstore(0x20, 0x80)
    13671
                mstore(0x40, 0xc0)
    13672
                mstore(0x60, p2)
    13673
                mstore(0x80, 0x100)
    13674
                writeString(0xa0, p0)
    13675
                writeString(0xe0, p1)
    13676
                writeString(0x120, p3)
    13677
            }
    13678
            _sendLogPayload(0x1c, 0x144);
    13679
            /// @solidity memory-safe-assembly
    13680
            assembly {
    13681
                mstore(0x00, m0)
    13682
                mstore(0x20, m1)
    13683
                mstore(0x40, m2)
    13684
                mstore(0x60, m3)
    13685
                mstore(0x80, m4)
    13686
                mstore(0xa0, m5)
    13687
                mstore(0xc0, m6)
    13688
                mstore(0xe0, m7)
    13689
                mstore(0x100, m8)
    13690
                mstore(0x120, m9)
    13691
                mstore(0x140, m10)
    13692
            }
    13693
        }
    13694
    13695
        function log(bytes32 p0, bytes32 p1, bytes32 p2, address p3) internal pure {
    13696
            bytes32 m0;
    13697
            bytes32 m1;
    13698
            bytes32 m2;
    13699
            bytes32 m3;
    13700
            bytes32 m4;
    13701
            bytes32 m5;
    13702
            bytes32 m6;
    13703
            bytes32 m7;
    13704
            bytes32 m8;
    13705
            bytes32 m9;
    13706
            bytes32 m10;
    13707
            /// @solidity memory-safe-assembly
    13708
            assembly {
    13709
                function writeString(pos, w) {
    13710
                    let length := 0
    13711
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    13712
                    mstore(pos, length)
    13713
                    let shift := sub(256, shl(3, length))
    13714
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    13715
                }
    13716
                m0 := mload(0x00)
    13717
                m1 := mload(0x20)
    13718
                m2 := mload(0x40)
    13719
                m3 := mload(0x60)
    13720
                m4 := mload(0x80)
    13721
                m5 := mload(0xa0)
    13722
                m6 := mload(0xc0)
    13723
                m7 := mload(0xe0)
    13724
                m8 := mload(0x100)
    13725
                m9 := mload(0x120)
    13726
                m10 := mload(0x140)
    13727
                // Selector of `log(string,string,string,address)`.
    13728
                mstore(0x00, 0x6d572f44)
    13729
                mstore(0x20, 0x80)
    13730
                mstore(0x40, 0xc0)
    13731
                mstore(0x60, 0x100)
    13732
                mstore(0x80, p3)
    13733
                writeString(0xa0, p0)
    13734
                writeString(0xe0, p1)
    13735
                writeString(0x120, p2)
    13736
            }
    13737
            _sendLogPayload(0x1c, 0x144);
    13738
            /// @solidity memory-safe-assembly
    13739
            assembly {
    13740
                mstore(0x00, m0)
    13741
                mstore(0x20, m1)
    13742
                mstore(0x40, m2)
    13743
                mstore(0x60, m3)
    13744
                mstore(0x80, m4)
    13745
                mstore(0xa0, m5)
    13746
                mstore(0xc0, m6)
    13747
                mstore(0xe0, m7)
    13748
                mstore(0x100, m8)
    13749
                mstore(0x120, m9)
    13750
                mstore(0x140, m10)
    13751
            }
    13752
        }
    13753
    13754
        function log(bytes32 p0, bytes32 p1, bytes32 p2, bool p3) internal pure {
    13755
            bytes32 m0;
    13756
            bytes32 m1;
    13757
            bytes32 m2;
    13758
            bytes32 m3;
    13759
            bytes32 m4;
    13760
            bytes32 m5;
    13761
            bytes32 m6;
    13762
            bytes32 m7;
    13763
            bytes32 m8;
    13764
            bytes32 m9;
    13765
            bytes32 m10;
    13766
            /// @solidity memory-safe-assembly
    13767
            assembly {
    13768
                function writeString(pos, w) {
    13769
                    let length := 0
    13770
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    13771
                    mstore(pos, length)
    13772
                    let shift := sub(256, shl(3, length))
    13773
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    13774
                }
    13775
                m0 := mload(0x00)
    13776
                m1 := mload(0x20)
    13777
                m2 := mload(0x40)
    13778
                m3 := mload(0x60)
    13779
                m4 := mload(0x80)
    13780
                m5 := mload(0xa0)
    13781
                m6 := mload(0xc0)
    13782
                m7 := mload(0xe0)
    13783
                m8 := mload(0x100)
    13784
                m9 := mload(0x120)
    13785
                m10 := mload(0x140)
    13786
                // Selector of `log(string,string,string,bool)`.
    13787
                mstore(0x00, 0x2c1754ed)
    13788
                mstore(0x20, 0x80)
    13789
                mstore(0x40, 0xc0)
    13790
                mstore(0x60, 0x100)
    13791
                mstore(0x80, p3)
    13792
                writeString(0xa0, p0)
    13793
                writeString(0xe0, p1)
    13794
                writeString(0x120, p2)
    13795
            }
    13796
            _sendLogPayload(0x1c, 0x144);
    13797
            /// @solidity memory-safe-assembly
    13798
            assembly {
    13799
                mstore(0x00, m0)
    13800
                mstore(0x20, m1)
    13801
                mstore(0x40, m2)
    13802
                mstore(0x60, m3)
    13803
                mstore(0x80, m4)
    13804
                mstore(0xa0, m5)
    13805
                mstore(0xc0, m6)
    13806
                mstore(0xe0, m7)
    13807
                mstore(0x100, m8)
    13808
                mstore(0x120, m9)
    13809
                mstore(0x140, m10)
    13810
            }
    13811
        }
    13812
    13813
        function log(bytes32 p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure {
    13814
            bytes32 m0;
    13815
            bytes32 m1;
    13816
            bytes32 m2;
    13817
            bytes32 m3;
    13818
            bytes32 m4;
    13819
            bytes32 m5;
    13820
            bytes32 m6;
    13821
            bytes32 m7;
    13822
            bytes32 m8;
    13823
            bytes32 m9;
    13824
            bytes32 m10;
    13825
            /// @solidity memory-safe-assembly
    13826
            assembly {
    13827
                function writeString(pos, w) {
    13828
                    let length := 0
    13829
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    13830
                    mstore(pos, length)
    13831
                    let shift := sub(256, shl(3, length))
    13832
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    13833
                }
    13834
                m0 := mload(0x00)
    13835
                m1 := mload(0x20)
    13836
                m2 := mload(0x40)
    13837
                m3 := mload(0x60)
    13838
                m4 := mload(0x80)
    13839
                m5 := mload(0xa0)
    13840
                m6 := mload(0xc0)
    13841
                m7 := mload(0xe0)
    13842
                m8 := mload(0x100)
    13843
                m9 := mload(0x120)
    13844
                m10 := mload(0x140)
    13845
                // Selector of `log(string,string,string,uint256)`.
    13846
                mstore(0x00, 0x8eafb02b)
    13847
                mstore(0x20, 0x80)
    13848
                mstore(0x40, 0xc0)
    13849
                mstore(0x60, 0x100)
    13850
                mstore(0x80, p3)
    13851
                writeString(0xa0, p0)
    13852
                writeString(0xe0, p1)
    13853
                writeString(0x120, p2)
    13854
            }
    13855
            _sendLogPayload(0x1c, 0x144);
    13856
            /// @solidity memory-safe-assembly
    13857
            assembly {
    13858
                mstore(0x00, m0)
    13859
                mstore(0x20, m1)
    13860
                mstore(0x40, m2)
    13861
                mstore(0x60, m3)
    13862
                mstore(0x80, m4)
    13863
                mstore(0xa0, m5)
    13864
                mstore(0xc0, m6)
    13865
                mstore(0xe0, m7)
    13866
                mstore(0x100, m8)
    13867
                mstore(0x120, m9)
    13868
                mstore(0x140, m10)
    13869
            }
    13870
        }
    13871
    13872
        function log(bytes32 p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure {
    13873
            bytes32 m0;
    13874
            bytes32 m1;
    13875
            bytes32 m2;
    13876
            bytes32 m3;
    13877
            bytes32 m4;
    13878
            bytes32 m5;
    13879
            bytes32 m6;
    13880
            bytes32 m7;
    13881
            bytes32 m8;
    13882
            bytes32 m9;
    13883
            bytes32 m10;
    13884
            bytes32 m11;
    13885
            bytes32 m12;
    13886
            /// @solidity memory-safe-assembly
    13887
            assembly {
    13888
                function writeString(pos, w) {
    13889
                    let length := 0
    13890
                    for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } }
    13891
                    mstore(pos, length)
    13892
                    let shift := sub(256, shl(3, length))
    13893
                    mstore(add(pos, 0x20), shl(shift, shr(shift, w)))
    13894
                }
    13895
                m0 := mload(0x00)
    13896
                m1 := mload(0x20)
    13897
                m2 := mload(0x40)
    13898
                m3 := mload(0x60)
    13899
                m4 := mload(0x80)
    13900
                m5 := mload(0xa0)
    13901
                m6 := mload(0xc0)
    13902
                m7 := mload(0xe0)
    13903
                m8 := mload(0x100)
    13904
                m9 := mload(0x120)
    13905
                m10 := mload(0x140)
    13906
                m11 := mload(0x160)
    13907
                m12 := mload(0x180)
    13908
                // Selector of `log(string,string,string,string)`.
    13909
                mstore(0x00, 0xde68f20a)
    13910
                mstore(0x20, 0x80)
    13911
                mstore(0x40, 0xc0)
    13912
                mstore(0x60, 0x100)
    13913
                mstore(0x80, 0x140)
    13914
                writeString(0xa0, p0)
    13915
                writeString(0xe0, p1)
    13916
                writeString(0x120, p2)
    13917
                writeString(0x160, p3)
    13918
            }
    13919
            _sendLogPayload(0x1c, 0x184);
    13920
            /// @solidity memory-safe-assembly
    13921
            assembly {
    13922
                mstore(0x00, m0)
    13923
                mstore(0x20, m1)
    13924
                mstore(0x40, m2)
    13925
                mstore(0x60, m3)
    13926
                mstore(0x80, m4)
    13927
                mstore(0xa0, m5)
    13928
                mstore(0xc0, m6)
    13929
                mstore(0xe0, m7)
    13930
                mstore(0x100, m8)
    13931
                mstore(0x120, m9)
    13932
                mstore(0x140, m10)
    13933
                mstore(0x160, m11)
    13934
                mstore(0x180, m12)
    13935
            }
    13936
        }
    13937
    }
    13938
    86.0% lib/setup-helpers/src/ActorManager.sol
    Lines covered: 13 / 15 (86.0%)
    1
    // SPDX-License-Identifier: GPL-2.0
    2
    pragma solidity ^0.8.0;
    3
    4
    import {BaseSetup} from "@chimera/BaseSetup.sol";
    5
    import {vm} from "@chimera/Hevm.sol";
    6
    import {EnumerableSet} from "./EnumerableSet.sol";
    7
    8
    /// @dev This is the source of truth for the actors being used in the test
    9
    /// @notice No actors should be used in the suite without being added here first
    10
    abstract contract ActorManager {
    11
        using EnumerableSet for EnumerableSet.AddressSet;
    12
    13
        ///@notice The current actor being used
    14
        address private _actor;
    15
    16
        ///@notice The list of all actors being used
    17
        EnumerableSet.AddressSet private _actors;
    18
    19
        // If the current target is address(0) then it has not been setup yet and should revert
    20
        error ActorNotSetup();
    21
        // Do not allow duplicates
    22
        error ActorExists();
    23
        // If the actor does not exist
    24
        error ActorNotAdded();
    25
        // Do not allow the default actor
    26
        error DefaultActor();
    27
    28
        /// @notice address(this) is the default actor
    29
        constructor() {
    30
            _actors.add(address(this));
    31
            _actor = address(this);
    32
        }
    33
    34
        /// @notice Returns the current active actor
    35
        function _getActor() internal view returns (address) {
    36
            return _actor;
    37
        }
    38
    39
        /// @notice Returns all actors being used
    40
        function _getActors() internal view returns (address[] memory) {
    41
            return _actors.values();
    42
        }
    43
    44
        /// @notice Adds an actor to the list of actors
    45
        function _addActor(address target) internal {
    46
            if (_actors.contains(target)) {
    47
                revert ActorExists();
    48
            }
    49
    50
            if (target == address(this)) {
    51
                revert DefaultActor();
    52
            }
    53
    54
            _actors.add(target);
    55
        }
    56
    57
        /// @notice Removes an actor from the list of actors
    58
        function _removeActor(address target) internal {
    59
            if (!_actors.contains(target)) {
    60
                revert ActorNotAdded();
    61
            }
    62
    63
            if (target == address(this)) {
    64
                revert DefaultActor();
    65
            }
    66
    67
            _actors.remove(target);
    68
        }
    69
    70
        /// @dev Expose this in the `TargetFunctions` contract to let the fuzzer switch actors
    71
        ///   NOTE: We revert if the entropy is greater than the number of actors, for Halmos compatibility
    72
        /// @dev This may reduce fuzzing performance if using multiple actors, if so add explicitly clamped handlers to ManagersTargets using the index of all added actors
    73
        /// @notice Switches the current actor based on the entropy
    74
        /// @param entropy The entropy to choose a random actor in the array for switching
    75
        /// @return target The new active actor
    76
        function _switchActor(uint256 entropy) internal returns (address target) {
    77
            target = _actors.at(entropy);
    78
            _actor = target;
    79
        }
    80
    }
    81
    88.0% lib/setup-helpers/src/AssetManager.sol
    Lines covered: 8 / 9 (88.0%)
    1
    // SPDX-License-Identifier: GPL-2.0
    2
    pragma solidity ^0.8.0;
    3
    4
    import {BaseSetup} from "@chimera/BaseSetup.sol";
    5
    import {vm} from "@chimera/Hevm.sol";
    6
    7
    import {EnumerableSet} from "./EnumerableSet.sol";
    8
    import {MockERC20} from "./MockERC20.sol";
    9
    10
    /// @dev Source of truth for the assets being used in the test
    11
    /// @notice No assets should be used in the suite without being added here first
    12
    abstract contract AssetManager {
    13
        using EnumerableSet for EnumerableSet.AddressSet;
    14
    15
        /// @notice The current target for this set of variables
    16
        address private __asset;
    17
    18
        /// @notice The list of all assets being used
    19
        EnumerableSet.AddressSet private _assets;
    20
    21
        // If the current target is address(0) then it has not been setup yet and should revert
    22
        error NotSetup();
    23
        // Do not allow duplicates
    24
        error Exists();
    25
        // Enable only added assets
    26
        error NotAdded();
    27
    28
        /// @notice Returns the current active asset
    29
        function _getAsset() internal view returns (address) {
    30
            if (__asset == address(0)) {
    31
                revert NotSetup();
    32
            }
    33
    34
            return __asset;
    35
        }
    36
    37
        /// @notice Returns all assets being used
    38
        function _getAssets() internal view returns (address[] memory) {
    39
            return _assets.values();
    40
        }
    41
    42
        /// @notice Creates a new asset and adds it to the list of assets
    43
        /// @param decimals The number of decimals for the asset
    44
        /// @return The address of the new asset
    45
        function _newAsset(uint8 decimals) internal returns (address) {
    46
            address asset_ = address(new MockERC20("Test Token", "TST", decimals)); // If names get confusing, concatenate the decimals to the name
    47
            _addAsset(asset_);
    48
            __asset = asset_; // sets the asset as the current asset
    49
            return asset_;
    50
        }
    51
    52
        /// @notice Adds an asset to the list of assets
    53
        /// @param target The address of the asset to add
    54
        function _addAsset(address target) internal {
    55
            if (_assets.contains(target)) {
    56
                revert Exists();
    57
            }
    58
    59
            _assets.add(target);
    60
        }
    61
    62
        /// @notice Removes an asset from the list of assets
    63
        /// @param target The address of the asset to remove
    64
        function _removeAsset(address target) internal {
    65
            if (!_assets.contains(target)) {
    66
                revert NotAdded();
    67
            }
    68
    69
            _assets.remove(target);
    70
        }
    71
    72
        /// @notice Switches the current asset based on the entropy
    73
        ///   NOTE: We revert if the entropy is greater than the number of actors, for Halmos compatibility
    74
        /// @param entropy The entropy to choose a random asset in the array for switching
    75
        function _switchAsset(uint256 entropy) internal {
    76
            address target = _assets.at(entropy);
    77
            __asset = target;
    78
        }
    79
    80
        /// === Approve & Mint Asset === ///
    81
    82
        /// @notice Mint initial balance and approve allowances for the active asset
    83
        /// @param actorsArray The array of actors to mint the asset to
    84
        /// @param approvalArray The array of addresses to approve the asset to
    85
        /// @param amount The amount of the asset to mint
    86
        function _finalizeAssetDeployment(address[] memory actorsArray, address[] memory approvalArray, uint256 amount)
    87
            internal
    88
        {
    89
            _mintAssetToAllActors(actorsArray, amount);
    90
            for (uint256 i; i < approvalArray.length; i++) {
    91
                _approveAssetToAddressForAllActors(actorsArray, approvalArray[i]);
    92
            }
    93
        }
    94
    95
        /// @notice Mint the asset to all actors
    96
        /// @param actorsArray The array of actors to mint the asset to
    97
        /// @param amount The amount of the asset to mint
    98
        function _mintAssetToAllActors(address[] memory actorsArray, uint256 amount) private {
    99
            // mint all actors
    100
            address[] memory assets = _getAssets();
    101
            for (uint256 i; i < assets.length; i++) {
    102
                for (uint256 j; j < actorsArray.length; j++) {
    103
                    vm.prank(actorsArray[j]);
    104
                    MockERC20(assets[i]).mint(actorsArray[j], amount);
    105
                }
    106
            }
    107
        }
    108
    109
        /// @notice Approve the asset to all actors
    110
        /// @param actorsArray The array of actors to approve the asset from
    111
        /// @param addressToApprove The address to approve the asset to
    112
        function _approveAssetToAddressForAllActors(address[] memory actorsArray, address addressToApprove) private {
    113
            // approve to all actors
    114
            address[] memory assets = _getAssets();
    115
            for (uint256 i; i < assets.length; i++) {
    116
                for (uint256 j; j < actorsArray.length; j++) {
    117
                    vm.prank(actorsArray[j]);
    118
                    MockERC20(assets[i]).approve(addressToApprove, type(uint256).max);
    119
                }
    120
            }
    121
        }
    122
    }
    123
    95.0% lib/setup-helpers/src/EnumerableSet.sol
    Lines covered: 20 / 21 (95.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)
    3
    // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.
    4
    5
    pragma solidity ^0.8.0;
    6
    7
    /**
    8
     * @dev Library for managing
    9
     * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
    10
     * types.
    11
     *
    12
     * Sets have the following properties:
    13
     *
    14
     * - Elements are added, removed, and checked for existence in constant time
    15
     * (O(1)).
    16
     * - Elements are enumerated in O(n). No guarantees are made on the ordering.
    17
     *
    18
     * ```solidity
    19
     * contract Example {
    20
     *     // Add the library methods
    21
     *     using EnumerableSet for EnumerableSet.AddressSet;
    22
     *
    23
     *     // Declare a set state variable
    24
     *     EnumerableSet.AddressSet private mySet;
    25
     * }
    26
     * ```
    27
     *
    28
     * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
    29
     * and `uint256` (`UintSet`) are supported.
    30
     *
    31
     * [WARNING]
    32
     * ====
    33
     * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
    34
     * unusable.
    35
     * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
    36
     *
    37
     * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
    38
     * array of EnumerableSet.
    39
     * ====
    40
     */
    41
    library EnumerableSet {
    42
        // To implement this library for multiple types with as little code
    43
        // repetition as possible, we write it in terms of a generic Set type with
    44
        // bytes32 values.
    45
        // The Set implementation uses private functions, and user-facing
    46
        // implementations (such as AddressSet) are just wrappers around the
    47
        // underlying Set.
    48
        // This means that we can only create new EnumerableSets for types that fit
    49
        // in bytes32.
    50
    51
        struct Set {
    52
            // Storage of set values
    53
            bytes32[] _values;
    54
            // Position of the value in the `values` array, plus 1 because index 0
    55
            // means a value is not in the set.
    56
            mapping(bytes32 => uint256) _indexes;
    57
        }
    58
    59
        /**
    60
         * @dev Add a value to a set. O(1).
    61
         *
    62
         * Returns true if the value was added to the set, that is if it was not
    63
         * already present.
    64
         */
    65
        function _add(Set storage set, bytes32 value) private returns (bool) {
    66
            if (!_contains(set, value)) {
    67
                set._values.push(value);
    68
                // The value is stored at length-1, but we add 1 to all indexes
    69
                // and use 0 as a sentinel value
    70
                set._indexes[value] = set._values.length;
    71
                return true;
    72
            } else {
    73
                return false;
    74
            }
    75
        }
    76
    77
        /**
    78
         * @dev Removes a value from a set. O(1).
    79
         *
    80
         * Returns true if the value was removed from the set, that is if it was
    81
         * present.
    82
         */
    83
        function _remove(Set storage set, bytes32 value) private returns (bool) {
    84
            // We read and store the value's index to prevent multiple reads from the same storage slot
    85
            uint256 valueIndex = set._indexes[value];
    86
    87
            if (valueIndex != 0) {
    88
                // Equivalent to contains(set, value)
    89
                // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
    90
                // the array, and then remove the last element (sometimes called as 'swap and pop').
    91
                // This modifies the order of the array, as noted in {at}.
    92
    93
                uint256 toDeleteIndex = valueIndex - 1;
    94
                uint256 lastIndex = set._values.length - 1;
    95
    96
                if (lastIndex != toDeleteIndex) {
    97
                    bytes32 lastValue = set._values[lastIndex];
    98
    99
                    // Move the last value to the index where the value to delete is
    100
                    set._values[toDeleteIndex] = lastValue;
    101
                    // Update the index for the moved value
    102
                    set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex
    103
                }
    104
    105
                // Delete the slot where the moved value was stored
    106
                set._values.pop();
    107
    108
                // Delete the index for the deleted slot
    109
                delete set._indexes[value];
    110
    111
                return true;
    112
            } else {
    113
                return false;
    114
            }
    115
        }
    116
    117
        /**
    118
         * @dev Returns true if the value is in the set. O(1).
    119
         */
    120
        function _contains(Set storage set, bytes32 value) private view returns (bool) {
    121
            return set._indexes[value] != 0;
    122
        }
    123
    124
        /**
    125
         * @dev Returns the number of values on the set. O(1).
    126
         */
    127
        function _length(Set storage set) private view returns (uint256) {
    128
            return set._values.length;
    129
        }
    130
    131
        /**
    132
         * @dev Returns the value stored at position `index` in the set. O(1).
    133
         *
    134
         * Note that there are no guarantees on the ordering of values inside the
    135
         * array, and it may change when more values are added or removed.
    136
         *
    137
         * Requirements:
    138
         *
    139
         * - `index` must be strictly less than {length}.
    140
         */
    141
        function _at(Set storage set, uint256 index) private view returns (bytes32) {
    142
            return set._values[index];
    143
        }
    144
    145
        /**
    146
         * @dev Return the entire set in an array
    147
         *
    148
         * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
    149
         * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
    150
         * this function has an unbounded cost, and using it as part of a state-changing function may render the function
    151
         * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
    152
         */
    153
        function _values(Set storage set) private view returns (bytes32[] memory) {
    154
            return set._values;
    155
        }
    156
    157
        // Bytes32Set
    158
    159
        struct Bytes32Set {
    160
            Set _inner;
    161
        }
    162
    163
        /**
    164
         * @dev Add a value to a set. O(1).
    165
         *
    166
         * Returns true if the value was added to the set, that is if it was not
    167
         * already present.
    168
         */
    169
        function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
    170
            return _add(set._inner, value);
    171
        }
    172
    173
        /**
    174
         * @dev Removes a value from a set. O(1).
    175
         *
    176
         * Returns true if the value was removed from the set, that is if it was
    177
         * present.
    178
         */
    179
        function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
    180
            return _remove(set._inner, value);
    181
        }
    182
    183
        /**
    184
         * @dev Returns true if the value is in the set. O(1).
    185
         */
    186
        function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
    187
            return _contains(set._inner, value);
    188
        }
    189
    190
        /**
    191
         * @dev Returns the number of values in the set. O(1).
    192
         */
    193
        function length(Bytes32Set storage set) internal view returns (uint256) {
    194
            return _length(set._inner);
    195
        }
    196
    197
        /**
    198
         * @dev Returns the value stored at position `index` in the set. O(1).
    199
         *
    200
         * Note that there are no guarantees on the ordering of values inside the
    201
         * array, and it may change when more values are added or removed.
    202
         *
    203
         * Requirements:
    204
         *
    205
         * - `index` must be strictly less than {length}.
    206
         */
    207
        function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
    208
            return _at(set._inner, index);
    209
        }
    210
    211
        /**
    212
         * @dev Return the entire set in an array
    213
         *
    214
         * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
    215
         * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
    216
         * this function has an unbounded cost, and using it as part of a state-changing function may render the function
    217
         * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
    218
         */
    219
        function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
    220
            bytes32[] memory store = _values(set._inner);
    221
            bytes32[] memory result;
    222
    223
            /// @solidity memory-safe-assembly
    224
            assembly {
    225
                result := store
    226
            }
    227
    228
            return result;
    229
        }
    230
    231
        // AddressSet
    232
    233
        struct AddressSet {
    234
            Set _inner;
    235
        }
    236
    237
        /**
    238
         * @dev Add a value to a set. O(1).
    239
         *
    240
         * Returns true if the value was added to the set, that is if it was not
    241
         * already present.
    242
         */
    243
        function add(AddressSet storage set, address value) internal returns (bool) {
    244
            return _add(set._inner, bytes32(uint256(uint160(value))));
    245
        }
    246
    247
        /**
    248
         * @dev Removes a value from a set. O(1).
    249
         *
    250
         * Returns true if the value was removed from the set, that is if it was
    251
         * present.
    252
         */
    253
        function remove(AddressSet storage set, address value) internal returns (bool) {
    254
            return _remove(set._inner, bytes32(uint256(uint160(value))));
    255
        }
    256
    257
        /**
    258
         * @dev Returns true if the value is in the set. O(1).
    259
         */
    260
        function contains(AddressSet storage set, address value) internal view returns (bool) {
    261
            return _contains(set._inner, bytes32(uint256(uint160(value))));
    262
        }
    263
    264
        /**
    265
         * @dev Returns the number of values in the set. O(1).
    266
         */
    267
        function length(AddressSet storage set) internal view returns (uint256) {
    268
            return _length(set._inner);
    269
        }
    270
    271
        /**
    272
         * @dev Returns the value stored at position `index` in the set. O(1).
    273
         *
    274
         * Note that there are no guarantees on the ordering of values inside the
    275
         * array, and it may change when more values are added or removed.
    276
         *
    277
         * Requirements:
    278
         *
    279
         * - `index` must be strictly less than {length}.
    280
         */
    281
        function at(AddressSet storage set, uint256 index) internal view returns (address) {
    282
            return address(uint160(uint256(_at(set._inner, index))));
    283
        }
    284
    285
        /**
    286
         * @dev Return the entire set in an array
    287
         *
    288
         * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
    289
         * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
    290
         * this function has an unbounded cost, and using it as part of a state-changing function may render the function
    291
         * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
    292
         */
    293
        function values(AddressSet storage set) internal view returns (address[] memory) {
    294
            bytes32[] memory store = _values(set._inner);
    295
            address[] memory result;
    296
    297
            /// @solidity memory-safe-assembly
    298
            assembly {
    299
                result := store
    300
            }
    301
    302
            return result;
    303
        }
    304
    305
        // UintSet
    306
    307
        struct UintSet {
    308
            Set _inner;
    309
        }
    310
    311
        /**
    312
         * @dev Add a value to a set. O(1).
    313
         *
    314
         * Returns true if the value was added to the set, that is if it was not
    315
         * already present.
    316
         */
    317
        function add(UintSet storage set, uint256 value) internal returns (bool) {
    318
            return _add(set._inner, bytes32(value));
    319
        }
    320
    321
        /**
    322
         * @dev Removes a value from a set. O(1).
    323
         *
    324
         * Returns true if the value was removed from the set, that is if it was
    325
         * present.
    326
         */
    327
        function remove(UintSet storage set, uint256 value) internal returns (bool) {
    328
            return _remove(set._inner, bytes32(value));
    329
        }
    330
    331
        /**
    332
         * @dev Returns true if the value is in the set. O(1).
    333
         */
    334
        function contains(UintSet storage set, uint256 value) internal view returns (bool) {
    335
            return _contains(set._inner, bytes32(value));
    336
        }
    337
    338
        /**
    339
         * @dev Returns the number of values in the set. O(1).
    340
         */
    341
        function length(UintSet storage set) internal view returns (uint256) {
    342
            return _length(set._inner);
    343
        }
    344
    345
        /**
    346
         * @dev Returns the value stored at position `index` in the set. O(1).
    347
         *
    348
         * Note that there are no guarantees on the ordering of values inside the
    349
         * array, and it may change when more values are added or removed.
    350
         *
    351
         * Requirements:
    352
         *
    353
         * - `index` must be strictly less than {length}.
    354
         */
    355
        function at(UintSet storage set, uint256 index) internal view returns (uint256) {
    356
            return uint256(_at(set._inner, index));
    357
        }
    358
    359
        /**
    360
         * @dev Return the entire set in an array
    361
         *
    362
         * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
    363
         * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
    364
         * this function has an unbounded cost, and using it as part of a state-changing function may render the function
    365
         * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
    366
         */
    367
        function values(UintSet storage set) internal view returns (uint256[] memory) {
    368
            bytes32[] memory store = _values(set._inner);
    369
            uint256[] memory result;
    370
    371
            /// @solidity memory-safe-assembly
    372
            assembly {
    373
                result := store
    374
            }
    375
    376
            return result;
    377
        }
    378
    }
    379
    0.0% lib/setup-helpers/src/MockERC20.sol
    Lines covered: 0 / 75 (0.0%)
    1
    // SPDX-License-Identifier: AGPL-3.0-only
    2
    pragma solidity ^0.8.0;
    3
    4
    /// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
    5
    /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)
    6
    /// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
    7
    /// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
    8
    abstract contract ERC20 {
    9
        /*//////////////////////////////////////////////////////////////
    10
                                     ERRORS
    11
        //////////////////////////////////////////////////////////////*/
    12
    13
        /// @notice Thrown when attempting to transfer more tokens than available balance
    14
        error InsufficientBalance(address from, uint256 balance, uint256 amount);
    15
    16
        /// @notice Thrown when attempting to transfer more tokens than allowed
    17
        error InsufficientAllowance(address owner, address spender, uint256 allowance, uint256 amount);
    18
    19
        /// @notice Thrown when minting would cause overflow
    20
        error MintOverflow(uint256 currentSupply, uint256 amount);
    21
    22
        /*//////////////////////////////////////////////////////////////
    23
                                     EVENTS
    24
        //////////////////////////////////////////////////////////////*/
    25
    26
        event Transfer(address indexed from, address indexed to, uint256 amount);
    27
    28
        event Approval(address indexed owner, address indexed spender, uint256 amount);
    29
    30
        /*//////////////////////////////////////////////////////////////
    31
                                METADATA STORAGE
    32
        //////////////////////////////////////////////////////////////*/
    33
    34
        string public name;
    35
    36
        string public symbol;
    37
    38
        uint8 public immutable decimals;
    39
    40
        /*//////////////////////////////////////////////////////////////
    41
                                  ERC20 STORAGE
    42
        //////////////////////////////////////////////////////////////*/
    43
    44
        uint256 public totalSupply;
    45
    46
        mapping(address => uint256) public balanceOf;
    47
    48
        mapping(address => mapping(address => uint256)) public allowance;
    49
    50
        /*//////////////////////////////////////////////////////////////
    51
                                EIP-2612 STORAGE
    52
        //////////////////////////////////////////////////////////////*/
    53
    54
        uint256 internal immutable INITIAL_CHAIN_ID;
    55
    56
        bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;
    57
    58
        mapping(address => uint256) public nonces;
    59
    60
        /*//////////////////////////////////////////////////////////////
    61
                                   CONSTRUCTOR
    62
        //////////////////////////////////////////////////////////////*/
    63
    64
        constructor(string memory _name, string memory _symbol, uint8 _decimals) {
    65
            name = _name;
    66
            symbol = _symbol;
    67
            decimals = _decimals;
    68
    69
            INITIAL_CHAIN_ID = block.chainid;
    70
            INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
    71
        }
    72
    73
        /*//////////////////////////////////////////////////////////////
    74
                                   ERC20 LOGIC
    75
        //////////////////////////////////////////////////////////////*/
    76
    77
        function approve(address spender, uint256 amount) public virtual returns (bool) {
    78
            allowance[msg.sender][spender] = amount;
    79
    80
            emit Approval(msg.sender, spender, amount);
    81
    82
            return true;
    83
        }
    84
    85
        function transfer(address to, uint256 amount) public virtual returns (bool) {
    86
            uint256 fromBalance = balanceOf[msg.sender];
    87
            if (fromBalance < amount) revert InsufficientBalance(msg.sender, fromBalance, amount);
    88
    89
            balanceOf[msg.sender] = fromBalance - amount;
    90
    91
            // Cannot overflow because the sum of all user
    92
            // balances can't exceed the max uint256 value.
    93
            unchecked {
    94
                balanceOf[to] += amount;
    95
            }
    96
    97
            emit Transfer(msg.sender, to, amount);
    98
    99
            return true;
    100
        }
    101
    102
        function transferFrom(address from, address to, uint256 amount) public virtual returns (bool) {
    103
            uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.
    104
            uint256 fromBalance = balanceOf[from];
    105
    106
            if (allowed != type(uint256).max) {
    107
                if (allowed < amount) revert InsufficientAllowance(from, msg.sender, allowed, amount);
    108
                allowance[from][msg.sender] = allowed - amount;
    109
            }
    110
    111
            if (fromBalance < amount) revert InsufficientBalance(from, fromBalance, amount);
    112
            balanceOf[from] = fromBalance - amount;
    113
    114
            // Cannot overflow because the sum of all user
    115
            // balances can't exceed the max uint256 value.
    116
            unchecked {
    117
                balanceOf[to] += amount;
    118
            }
    119
    120
            emit Transfer(from, to, amount);
    121
    122
            return true;
    123
        }
    124
    125
        /*//////////////////////////////////////////////////////////////
    126
                                 EIP-2612 LOGIC
    127
        //////////////////////////////////////////////////////////////*/
    128
    129
        function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)
    130
            public
    131
            virtual
    132
        {
    133
            require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");
    134
    135
            // Unchecked because the only math done is incrementing
    136
            // the owner's nonce which cannot realistically overflow.
    137
            unchecked {
    138
                address recoveredAddress = ecrecover(
    139
                    keccak256(
    140
                        abi.encodePacked(
    141
                            "\x19\x01",
    142
                            DOMAIN_SEPARATOR(),
    143
                            keccak256(
    144
                                abi.encode(
    145
                                    keccak256(
    146
                                        "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
    147
                                    ),
    148
                                    owner,
    149
                                    spender,
    150
                                    value,
    151
                                    nonces[owner]++,
    152
                                    deadline
    153
                                )
    154
                            )
    155
                        )
    156
                    ),
    157
                    v,
    158
                    r,
    159
                    s
    160
                );
    161
    162
                require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");
    163
    164
                allowance[recoveredAddress][spender] = value;
    165
            }
    166
    167
            emit Approval(owner, spender, value);
    168
        }
    169
    170
        function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
    171
            return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
    172
        }
    173
    174
        function computeDomainSeparator() internal view virtual returns (bytes32) {
    175
            return keccak256(
    176
                abi.encode(
    177
                    keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
    178
                    keccak256(bytes(name)),
    179
                    keccak256("1"),
    180
                    block.chainid,
    181
                    address(this)
    182
                )
    183
            );
    184
        }
    185
    186
        /*//////////////////////////////////////////////////////////////
    187
                            INTERNAL MINT/BURN LOGIC
    188
        //////////////////////////////////////////////////////////////*/
    189
    190
        function _mint(address to, uint256 amount) internal virtual {
    191
            uint256 newTotalSupply = totalSupply + amount;
    192
            if (newTotalSupply < totalSupply) revert MintOverflow(totalSupply, amount);
    193
            totalSupply = newTotalSupply;
    194
    195
            // Cannot overflow because the sum of all user
    196
            // balances can't exceed the max uint256 value.
    197
            unchecked {
    198
                balanceOf[to] += amount;
    199
            }
    200
    201
            emit Transfer(address(0), to, amount);
    202
        }
    203
    204
        function _burn(address from, uint256 amount) internal virtual {
    205
            uint256 fromBalance = balanceOf[from];
    206
            if (fromBalance < amount) revert InsufficientBalance(from, fromBalance, amount);
    207
    208
            balanceOf[from] = fromBalance - amount;
    209
    210
            // Cannot underflow because a user's balance
    211
            // will never be larger than the total supply.
    212
            unchecked {
    213
                totalSupply -= amount;
    214
            }
    215
    216
            emit Transfer(from, address(0), amount);
    217
        }
    218
    }
    219
    220
    contract MockERC20 is ERC20 {
    221
        constructor(string memory _name, string memory _symbol, uint8 _decimals) ERC20(_name, _symbol, _decimals) {}
    222
    223
        function mint(address to, uint256 value) public virtual {
    224
            _mint(to, value);
    225
        }
    226
    227
        function burn(address from, uint256 value) public virtual {
    228
            _burn(from, value);
    229
        }
    230
    }
    231
    100.0% lib/setup-helpers/src/Panic.sol
    Lines covered: 1 / 1 (100.0%)
    1
    // SPDX-License-Identifier: GPL-2.0
    2
    pragma solidity ^0.8.0;
    3
    4
    library Panic {
    5
        // compiler panics
    6
        string constant assertionPanic = "Panic(1)";
    7
        string constant arithmeticPanic = "Panic(17)";
    8
        string constant divisionPanic = "Panic(18)";
    9
        string constant enumPanic = "Panic(33)";
    10
        string constant arrayPanic = "Panic(34)";
    11
        string constant emptyArrayPanic = "Panic(49)";
    12
        string constant outOfBoundsPanic = "Panic(50)";
    13
        string constant memoryPanic = "Panic(65)";
    14
        string constant functionPanic = "Panic(81)";
    15
    }
    16
    0.0% lib/setup-helpers/src/Utils.sol
    Lines covered: 0 / 1 (0.0%)
    1
    // SPDX-License-Identifier: GPL-2.0
    2
    pragma solidity ^0.8.0;
    3
    4
    import {Panic} from "./Panic.sol";
    5
    6
    contract Utils {
    7
        /// @dev check if the error returned from a call is the same as the expected error
    8
        /// @param err the error returned from a call
    9
        /// @param expected the expected error
    10
        /// @return true if the error is the same as the expected error, false otherwise
    11
        function checkError(bytes memory err, string memory expected) internal pure returns (bool) {
    12
            (string memory revertMsg, bool customError) = _getRevertMsg(err);
    13
    14
            bytes32 errorBytes;
    15
            bytes32 expectedBytes;
    16
    17
            if (customError) {
    18
                // Custom error returns the keccak256 hash of the error, so don't need to hash it again
    19
                errorBytes = bytes32(abi.encodePacked(revertMsg, bytes28(0)));
    20
                expectedBytes = bytes4(keccak256(abi.encodePacked(expected)));
    21
            } else {
    22
                errorBytes = keccak256(abi.encodePacked(revertMsg));
    23
                expectedBytes = keccak256(abi.encodePacked(expected));
    24
            }
    25
    26
            // Check if error contains expected string
    27
            return errorBytes == expectedBytes;
    28
        }
    29
    30
        /// @dev get the revert message from a call
    31
        /// @notice based on https://ethereum.stackexchange.com/a/83577
    32
        /// @param returnData the return data from a call
    33
        /// @return the revert message and a boolean indicating if it's a custom error
    34
        function _getRevertMsg(bytes memory returnData) internal pure returns (string memory, bool) {
    35
            // If the returnData length is 0, then the transaction failed silently (without a revert message)
    36
            if (returnData.length == 0) return ("", false);
    37
    38
            // 1. Panic(uint256)
    39
            // Check that the data has the right size: 4 bytes for signature + 32 bytes for panic code
    40
            if (returnData.length == 4 + 32) {
    41
                // Check that the data starts with the Panic signature
    42
                bool panic = _checkIfPanic(returnData);
    43
    44
                if (panic) {
    45
                    return _getPanicCode(returnData);
    46
                }
    47
            }
    48
    49
            // Get the error selector from returnData
    50
            bytes4 errorSelector = _getErrorSelector(returnData);
    51
    52
            // 2. Error(string) - If it's a standard revert string
    53
            bytes4 errorStringSelector = bytes4(keccak256("Error(string)")); // Get the standard Error(string) selector
    54
    55
            if (errorSelector == errorStringSelector) {
    56
                assembly {
    57
                    // slice the sighash of the error so we can decode the string
    58
                    returnData := add(returnData, 0x04)
    59
                }
    60
                return (abi.decode(returnData, (string)), false);
    61
            }
    62
    63
            // 3. Custom error - Return the custom error selector as a string
    64
            return (string(abi.encodePacked(errorSelector)), true);
    65
        }
    66
    67
        function _checkIfPanic(bytes memory returnData) internal pure returns (bool) {
    68
            bytes4 panicSignature = bytes4(keccak256(bytes("Panic(uint256)")));
    69
    70
            for (uint256 i = 0; i < 4; i++) {
    71
                if (returnData[i] != panicSignature[i]) {
    72
                    return false;
    73
                }
    74
            }
    75
    76
            return true;
    77
        }
    78
    79
        function _getPanicCode(bytes memory returnData) internal pure returns (string memory, bool) {
    80
            uint256 panicCode;
    81
            for (uint256 i = 4; i < 36; i++) {
    82
                panicCode = panicCode << 8;
    83
                panicCode |= uint8(returnData[i]);
    84
            }
    85
    86
            // Convert the panic code into its string representation
    87
            if (panicCode == 1) {
    88
                // call assert with an argument that evaluates to false
    89
                return (Panic.assertionPanic, false);
    90
            } else if (panicCode == 17) {
    91
                // arithmetic operation results in underflow or overflow
    92
                return (Panic.arithmeticPanic, false);
    93
            } else if (panicCode == 18) {
    94
                // division or modulo by zero
    95
                return (Panic.divisionPanic, false);
    96
            } else if (panicCode == 33) {
    97
                // converting a value that's too big or negative into an enum type
    98
                return (Panic.enumPanic, false);
    99
            } else if (panicCode == 34) {
    100
                // access a storage byte array that is incorrectly encoded
    101
                return (Panic.arrayPanic, false);
    102
            } else if (panicCode == 49) {
    103
                // call .pop() on an empty array
    104
                return (Panic.emptyArrayPanic, false);
    105
            } else if (panicCode == 50) {
    106
                // array access out of bounds
    107
                return (Panic.outOfBoundsPanic, false);
    108
            } else if (panicCode == 65) {
    109
                // allocate too much memory or create an array that is too large
    110
                return (Panic.memoryPanic, false);
    111
            } else if (panicCode == 81) {
    112
                // call a zero-initialized variable of internal function type
    113
                return (Panic.functionPanic, false);
    114
            }
    115
    116
            return ("Undefined panic code", false);
    117
        }
    118
    119
        function _getErrorSelector(bytes memory returnData) internal pure returns (bytes4 errorSelector) {
    120
            assembly {
    121
                errorSelector := mload(add(returnData, 0x20))
    122
            }
    123
            return errorSelector;
    124
        }
    125
    }
    126
    41.0% src/access/AccessManagerEnumerable.sol
    Lines covered: 15 / 36 (41.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity 0.8.28;
    4
    5
    import {AccessManager} from 'src/dependencies/openzeppelin/AccessManager.sol';
    6
    import {EnumerableSet} from 'src/dependencies/openzeppelin/EnumerableSet.sol';
    7
    import {IAccessManagerEnumerable} from 'src/access/interfaces/IAccessManagerEnumerable.sol';
    8
    9
    /// @title AccessManagerEnumerable
    10
    /// @author Aave Labs
    11
    /// @notice Extension of AccessManager that tracks role members and their function selectors using EnumerableSet.
    12
    contract AccessManagerEnumerable is AccessManager, IAccessManagerEnumerable {
    13
      using EnumerableSet for EnumerableSet.AddressSet;
    14
      using EnumerableSet for EnumerableSet.Bytes32Set;
    15
    16
      /// @dev Map of role identifiers to their respective member sets.
    17
      mapping(uint64 roleId => EnumerableSet.AddressSet) private _roleMembers;
    18
    19
      /// @dev Map of role identifiers and target contract addresses to their respective set of function selectors.
    20
      mapping(uint64 roleId => mapping(address target => EnumerableSet.Bytes32Set))
    21
        private _roleTargetFunctions;
    22
    23
      constructor(address initialAdmin_) AccessManager(initialAdmin_) {}
    24
    25
      /// @inheritdoc IAccessManagerEnumerable
    26
      function getRoleMember(uint64 roleId, uint256 index) external view returns (address) {
    27
        return _roleMembers[roleId].at(index);
    28
      }
    29
    30
      /// @inheritdoc IAccessManagerEnumerable
    31
      function getRoleMemberCount(uint64 roleId) external view returns (uint256) {
    32
        return _roleMembers[roleId].length();
    33
      }
    34
    35
      /// @inheritdoc IAccessManagerEnumerable
    36
      function getRoleMembers(
    37
        uint64 roleId,
    38
        uint256 start,
    39
        uint256 end
    40
      ) external view returns (address[] memory) {
    41
        return _roleMembers[roleId].values(start, end);
    42
      }
    43
    44
      /// @inheritdoc IAccessManagerEnumerable
    45
      function getRoleTargetFunction(
    46
        uint64 roleId,
    47
        address target,
    48
        uint256 index
    49
      ) external view returns (bytes4) {
    50
        return bytes4(_roleTargetFunctions[roleId][target].at(index));
    51
      }
    52
    53
      /// @inheritdoc IAccessManagerEnumerable
    54
      function getRoleTargetFunctionCount(
    55
        uint64 roleId,
    56
        address target
    57
      ) external view returns (uint256) {
    58
        return _roleTargetFunctions[roleId][target].length();
    59
      }
    60
    61
      /// @inheritdoc IAccessManagerEnumerable
    62
      function getRoleTargetFunctions(
    63
        uint64 roleId,
    64
        address target,
    65
        uint256 start,
    66
        uint256 end
    67
      ) external view returns (bytes4[] memory) {
    68
        bytes32[] memory targetFunctions = _roleTargetFunctions[roleId][target].values(start, end);
    69
        bytes4[] memory targetFunctionSelectors;
    70
        assembly ('memory-safe') {
    71
          targetFunctionSelectors := targetFunctions
    72
        }
    73
        return targetFunctionSelectors;
    74
      }
    75
    76
      /// @dev Override AccessManager `_grantRole` function to track role members.
    77
      function _grantRole(
    78
        uint64 roleId,
    79
        address account,
    80
        uint32 grantDelay,
    81
        uint32 executionDelay
    82
      ) internal override returns (bool) {
    83
        bool granted = super._grantRole(roleId, account, grantDelay, executionDelay);
    84
        if (granted) {
    85
          _roleMembers[roleId].add(account);
    86
        }
    87
        return granted;
    88
      }
    89
    90
      /// @dev Override AccessManager `_revokeRole` function to remove from tracked role members.
    91
      function _revokeRole(uint64 roleId, address account) internal override returns (bool) {
    92
        bool revoked = super._revokeRole(roleId, account);
    93
        if (revoked) {
    94
          _roleMembers[roleId].remove(account);
    95
        }
    96
        return revoked;
    97
      }
    98
    99
      /// @dev Override AccessManager `_setTargetFunctionRole` function to track function selectors attributed to roles.
    100
      function _setTargetFunctionRole(
    101
        address target,
    102
        bytes4 selector,
    103
        uint64 roleId
    104
      ) internal override {
    105
        uint64 oldRoleId = getTargetFunctionRole(target, selector);
    106
        super._setTargetFunctionRole(target, selector, roleId);
    107
        if (oldRoleId != ADMIN_ROLE) {
    108
          _roleTargetFunctions[oldRoleId][target].remove(bytes32(selector));
    109
        }
    110
        if (roleId != ADMIN_ROLE) {
    111
          _roleTargetFunctions[roleId][target].add(bytes32(selector));
    112
        }
    113
      }
    114
    }
    115
    0.0% src/access/interfaces/IAccessManagerEnumerable.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    import {IAccessManager} from 'src/dependencies/openzeppelin/IAccessManager.sol';
    6
    7
    /// @title IAccessManagerEnumerable
    8
    /// @author Aave Labs
    9
    /// @notice Interface for AccessManagerEnumerable extension.
    10
    interface IAccessManagerEnumerable is IAccessManager {
    11
      /// @notice Returns the address of the role member at a specified index.
    12
      /// @param roleId The identifier of the role.
    13
      /// @param index The index in the role member list.
    14
      /// @return The address of the role member.
    15
      function getRoleMember(uint64 roleId, uint256 index) external view returns (address);
    16
    17
      /// @notice Returns the number of members for a specified role.
    18
      /// @param roleId The identifier of the role.
    19
      /// @return The number of members for the role.
    20
      function getRoleMemberCount(uint64 roleId) external view returns (uint256);
    21
    22
      /// @notice Returns the list of members for a specified role.
    23
      /// @param roleId The identifier of the role.
    24
      /// @param start The starting index for the member list.
    25
      /// @param end The ending index for the member list.
    26
      /// @return The list of members for the role.
    27
      function getRoleMembers(
    28
        uint64 roleId,
    29
        uint256 start,
    30
        uint256 end
    31
      ) external view returns (address[] memory);
    32
    33
      /// @notice Returns the function selector assigned to a given role at the specified index.
    34
      /// @param roleId The identifier of the role.
    35
      /// @param target The address of the target contract.
    36
      /// @param index The index in the role member list.
    37
      /// @return The selector at the index.
    38
      function getRoleTargetFunction(
    39
        uint64 roleId,
    40
        address target,
    41
        uint256 index
    42
      ) external view returns (bytes4);
    43
    44
      /// @notice Returns the number of function selectors assigned to the given role.
    45
      /// @param roleId The identifier of the role.
    46
      /// @param target The address of the target contract.
    47
      /// @return The number of selectors assigned to the role.
    48
      function getRoleTargetFunctionCount(
    49
        uint64 roleId,
    50
        address target
    51
      ) external view returns (uint256);
    52
    53
      /// @notice Returns the list of function selectors assigned to the given role between the specified indexes.
    54
      /// @param roleId The identifier of the role.
    55
      /// @param target The address of the target contract.
    56
      /// @param start The starting index for the selector list.
    57
      /// @param end The ending index for the selector list.
    58
      /// @return The list of selectors assigned to the role.
    59
      function getRoleTargetFunctions(
    60
        uint64 roleId,
    61
        address target,
    62
        uint256 start,
    63
        uint256 end
    64
      ) external view returns (bytes4[] memory);
    65
    }
    66
    59.0% src/dependencies/openzeppelin/AccessManaged.sol
    Lines covered: 13 / 22 (59.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.4.0) (access/manager/AccessManaged.sol)
    3
    4
    pragma solidity ^0.8.20;
    5
    6
    import {AuthorityUtils} from './AuthorityUtils.sol';
    7
    import {IAccessManager} from './IAccessManager.sol';
    8
    import {IAccessManaged} from './IAccessManaged.sol';
    9
    import {Context} from './Context.sol';
    10
    11
    /**
    12
     * @dev This contract module makes available a {restricted} modifier. Functions decorated with this modifier will be
    13
     * permissioned according to an "authority": a contract like {AccessManager} that follows the {IAuthority} interface,
    14
     * implementing a policy that allows certain callers to access certain functions.
    15
     *
    16
     * IMPORTANT: The `restricted` modifier should never be used on `internal` functions, judiciously used in `public`
    17
     * functions, and ideally only used in `external` functions. See {restricted}.
    18
     */
    19
    abstract contract AccessManaged is Context, IAccessManaged {
    20
      address private _authority;
    21
    22
      bool private _consumingSchedule;
    23
    24
      /**
    25
       * @dev Initializes the contract connected to an initial authority.
    26
       */
    27
      constructor(address initialAuthority) {
    28
        _setAuthority(initialAuthority);
    29
      }
    30
    31
      /**
    32
       * @dev Restricts access to a function as defined by the connected Authority for this contract and the
    33
       * caller and selector of the function that entered the contract.
    34
       *
    35
       * [IMPORTANT]
    36
       * ====
    37
       * In general, this modifier should only be used on `external` functions. It is okay to use it on `public`
    38
       * functions that are used as external entry points and are not called internally. Unless you know what you're
    39
       * doing, it should never be used on `internal` functions. Failure to follow these rules can have critical security
    40
       * implications! This is because the permissions are determined by the function that entered the contract, i.e. the
    41
       * function at the bottom of the call stack, and not the function where the modifier is visible in the source code.
    42
       * ====
    43
       *
    44
       * [WARNING]
    45
       * ====
    46
       * Avoid adding this modifier to the https://docs.soliditylang.org/en/v0.8.20/contracts.html#receive-ether-function[`receive()`]
    47
       * function or the https://docs.soliditylang.org/en/v0.8.20/contracts.html#fallback-function[`fallback()`]. These
    48
       * functions are the only execution paths where a function selector cannot be unambiguously determined from the calldata
    49
       * since the selector defaults to `0x00000000` in the `receive()` function and similarly in the `fallback()` function
    50
       * if no calldata is provided. (See {_checkCanCall}).
    51
       *
    52
       * The `receive()` function will always panic whereas the `fallback()` may panic depending on the calldata length.
    53
       * ====
    54
       */
    55
      modifier restricted() {
    56
        _checkCanCall(_msgSender(), _msgData());
    57
        _;
    58
      }
    59
    60
      /// @inheritdoc IAccessManaged
    61
      function authority() public view virtual returns (address) {
    62
        return _authority;
    63
      }
    64
    65
      /// @inheritdoc IAccessManaged
    66
      function setAuthority(address newAuthority) public virtual {
    67
        address caller = _msgSender();
    68
        if (caller != authority()) {
    69
          revert AccessManagedUnauthorized(caller);
    70
        }
    71
        if (newAuthority.code.length == 0) {
    72
          revert AccessManagedInvalidAuthority(newAuthority);
    73
        }
    74
        _setAuthority(newAuthority);
    75
      }
    76
    77
      /// @inheritdoc IAccessManaged
    78
      function isConsumingScheduledOp() public view returns (bytes4) {
    79
        return _consumingSchedule ? this.isConsumingScheduledOp.selector : bytes4(0);
    80
      }
    81
    82
      /**
    83
       * @dev Transfers control to a new authority. Internal function with no access restriction. Allows bypassing the
    84
       * permissions set by the current authority.
    85
       */
    86
      function _setAuthority(address newAuthority) internal virtual {
    87
        _authority = newAuthority;
    88
        emit AuthorityUpdated(newAuthority);
    89
      }
    90
    91
      /**
    92
       * @dev Reverts if the caller is not allowed to call the function identified by a selector. Panics if the calldata
    93
       * is less than 4 bytes long.
    94
       */
    95
      function _checkCanCall(address caller, bytes calldata data) internal virtual {
    96
        (bool immediate, uint32 delay) = AuthorityUtils.canCallWithDelay(
    97
          authority(),
    98
          caller,
    99
          address(this),
    100
          bytes4(data[0:4])
    101
        );
    102
        if (!immediate) {
    103
          if (delay > 0) {
    104
            _consumingSchedule = true;
    105
            IAccessManager(authority()).consumeScheduledOp(caller, data);
    106
            _consumingSchedule = false;
    107
          } else {
    108
            revert AccessManagedUnauthorized(caller);
    109
          }
    110
        }
    111
      }
    112
    }
    113
    100.0% src/dependencies/openzeppelin/AccessManager.sol
    Lines covered: 3 / 3 (100.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.1.0) (access/manager/AccessManager.sol)
    3
    4
    pragma solidity ^0.8.20;
    5
    6
    import {IAccessManager} from './IAccessManager.sol';
    7
    import {IAccessManaged} from './IAccessManaged.sol';
    8
    import {Address} from './Address.sol';
    9
    import {Context} from './Context.sol';
    10
    import {Multicall} from './Multicall.sol';
    11
    import {Math} from './Math.sol';
    12
    import {Time} from './Time.sol';
    13
    14
    /**
    15
     * @dev AccessManager is a central contract to store the permissions of a system.
    16
     *
    17
     * A smart contract under the control of an AccessManager instance is known as a target, and will inherit from the
    18
     * {AccessManaged} contract, be connected to this contract as its manager and implement the {AccessManaged-restricted}
    19
     * modifier on a set of functions selected to be permissioned. Note that any function without this setup won't be
    20
     * effectively restricted.
    21
     *
    22
     * The restriction rules for such functions are defined in terms of "roles" identified by an `uint64` and scoped
    23
     * by target (`address`) and function selectors (`bytes4`). These roles are stored in this contract and can be
    24
     * configured by admins (`ADMIN_ROLE` members) after a delay (see {getTargetAdminDelay}).
    25
     *
    26
     * For each target contract, admins can configure the following without any delay:
    27
     *
    28
     * * The target's {AccessManaged-authority} via {updateAuthority}.
    29
     * * Close or open a target via {setTargetClosed} keeping the permissions intact.
    30
     * * The roles that are allowed (or disallowed) to call a given function (identified by its selector) through {setTargetFunctionRole}.
    31
     *
    32
     * By default every address is member of the `PUBLIC_ROLE` and every target function is restricted to the `ADMIN_ROLE` until configured otherwise.
    33
     * Additionally, each role has the following configuration options restricted to this manager's admins:
    34
     *
    35
     * * A role's admin role via {setRoleAdmin} who can grant or revoke roles.
    36
     * * A role's guardian role via {setRoleGuardian} who's allowed to cancel operations.
    37
     * * A delay in which a role takes effect after being granted through {setGrantDelay}.
    38
     * * A delay of any target's admin action via {setTargetAdminDelay}.
    39
     * * A role label for discoverability purposes with {labelRole}.
    40
     *
    41
     * Any account can be added and removed into any number of these roles by using the {grantRole} and {revokeRole} functions
    42
     * restricted to each role's admin (see {getRoleAdmin}).
    43
     *
    44
     * Since all the permissions of the managed system can be modified by the admins of this instance, it is expected that
    45
     * they will be highly secured (e.g., a multisig or a well-configured DAO).
    46
     *
    47
     * NOTE: This contract implements a form of the {IAuthority} interface, but {canCall} has additional return data so it
    48
     * doesn't inherit `IAuthority`. It is however compatible with the `IAuthority` interface since the first 32 bytes of
    49
     * the return data are a boolean as expected by that interface.
    50
     *
    51
     * NOTE: Systems that implement other access control mechanisms (for example using {Ownable}) can be paired with an
    52
     * {AccessManager} by transferring permissions (ownership in the case of {Ownable}) directly to the {AccessManager}.
    53
     * Users will be able to interact with these contracts through the {execute} function, following the access rules
    54
     * registered in the {AccessManager}. Keep in mind that in that context, the msg.sender seen by restricted functions
    55
     * will be {AccessManager} itself.
    56
     *
    57
     * WARNING: When granting permissions over an {Ownable} or {AccessControl} contract to an {AccessManager}, be very
    58
     * mindful of the danger associated with functions such as {Ownable-renounceOwnership} or
    59
     * {AccessControl-renounceRole}.
    60
     */
    61
    contract AccessManager is Context, Multicall, IAccessManager {
    62
      using Time for *;
    63
    64
      // Structure that stores the details for a target contract.
    65
      struct TargetConfig {
    66
        mapping(bytes4 selector => uint64 roleId) allowedRoles;
    67
        Time.Delay adminDelay;
    68
        bool closed;
    69
      }
    70
    71
      // Structure that stores the details for a role/account pair. This structures fit into a single slot.
    72
      struct Access {
    73
        // Timepoint at which the user gets the permission.
    74
        // If this is either 0 or in the future, then the role permission is not available.
    75
        uint48 since;
    76
        // Delay for execution. Only applies to restricted() / execute() calls.
    77
        Time.Delay delay;
    78
      }
    79
    80
      // Structure that stores the details of a role.
    81
      struct Role {
    82
        // Members of the role.
    83
        mapping(address user => Access access) members;
    84
        // Admin who can grant or revoke permissions.
    85
        uint64 admin;
    86
        // Guardian who can cancel operations targeting functions that need this role.
    87
        uint64 guardian;
    88
        // Delay in which the role takes effect after being granted.
    89
        Time.Delay grantDelay;
    90
      }
    91
    92
      // Structure that stores the details for a scheduled operation. This structure fits into a single slot.
    93
      struct Schedule {
    94
        // Moment at which the operation can be executed.
    95
        uint48 timepoint;
    96
        // Operation nonce to allow third-party contracts to identify the operation.
    97
        uint32 nonce;
    98
      }
    99
    100
      /**
    101
       * @dev The identifier of the admin role. Required to perform most configuration operations including
    102
       * other roles' management and target restrictions.
    103
       */
    104
      uint64 public constant ADMIN_ROLE = type(uint64).min; // 0
    105
    106
      /**
    107
       * @dev The identifier of the public role. Automatically granted to all addresses with no delay.
    108
       */
    109
      uint64 public constant PUBLIC_ROLE = type(uint64).max; // 2**64-1
    110
    111
      mapping(address target => TargetConfig mode) private _targets;
    112
      mapping(uint64 roleId => Role) private _roles;
    113
      mapping(bytes32 operationId => Schedule) private _schedules;
    114
    115
      // Used to identify operations that are currently being executed via {execute}.
    116
      // This should be transient storage when supported by the EVM.
    117
      bytes32 private _executionId;
    118
    119
      /**
    120
       * @dev Check that the caller is authorized to perform the operation.
    121
       * See {AccessManager} description for a detailed breakdown of the authorization logic.
    122
       */
    123
      modifier onlyAuthorized() {
    124
        _checkAuthorized();
    125
        _;
    126
      }
    127
    128
      constructor(address initialAdmin) {
    129
        if (initialAdmin == address(0)) {
    130
          revert AccessManagerInvalidInitialAdmin(address(0));
    131
        }
    132
    133
        // admin is active immediately and without any execution delay.
    134
        _grantRole(ADMIN_ROLE, initialAdmin, 0, 0);
    135
      }
    136
    137
      // =================================================== GETTERS ====================================================
    138
      /// @inheritdoc IAccessManager
    139
      function canCall(
    140
        address caller,
    141
        address target,
    142
        bytes4 selector
    143
      ) public view virtual returns (bool immediate, uint32 delay) {
    144
        if (isTargetClosed(target)) {
    145
          return (false, 0);
    146
        } else if (caller == address(this)) {
    147
          // Caller is AccessManager, this means the call was sent through {execute} and it already checked
    148
          // permissions. We verify that the call "identifier", which is set during {execute}, is correct.
    149
          return (_isExecuting(target, selector), 0);
    150
        } else {
    151
          uint64 roleId = getTargetFunctionRole(target, selector);
    152
          (bool isMember, uint32 currentDelay) = hasRole(roleId, caller);
    153
          return isMember ? (currentDelay == 0, currentDelay) : (false, 0);
    154
        }
    155
      }
    156
    157
      /// @inheritdoc IAccessManager
    158
      function expiration() public view virtual returns (uint32) {
    159
        return 1 weeks;
    160
      }
    161
    162
      /// @inheritdoc IAccessManager
    163
      function minSetback() public view virtual returns (uint32) {
    164
        return 5 days;
    165
      }
    166
    167
      /// @inheritdoc IAccessManager
    168
      function isTargetClosed(address target) public view virtual returns (bool) {
    169
        return _targets[target].closed;
    170
      }
    171
    172
      /// @inheritdoc IAccessManager
    173
      function getTargetFunctionRole(
    174
        address target,
    175
        bytes4 selector
    176
      ) public view virtual returns (uint64) {
    177
        return _targets[target].allowedRoles[selector];
    178
      }
    179
    180
      /// @inheritdoc IAccessManager
    181
      function getTargetAdminDelay(address target) public view virtual returns (uint32) {
    182
        return _targets[target].adminDelay.get();
    183
      }
    184
    185
      /// @inheritdoc IAccessManager
    186
      function getRoleAdmin(uint64 roleId) public view virtual returns (uint64) {
    187
        return _roles[roleId].admin;
    188
      }
    189
    190
      /// @inheritdoc IAccessManager
    191
      function getRoleGuardian(uint64 roleId) public view virtual returns (uint64) {
    192
        return _roles[roleId].guardian;
    193
      }
    194
    195
      /// @inheritdoc IAccessManager
    196
      function getRoleGrantDelay(uint64 roleId) public view virtual returns (uint32) {
    197
        return _roles[roleId].grantDelay.get();
    198
      }
    199
    200
      /// @inheritdoc IAccessManager
    201
      function getAccess(
    202
        uint64 roleId,
    203
        address account
    204
      )
    205
        public
    206
        view
    207
        virtual
    208
        returns (uint48 since, uint32 currentDelay, uint32 pendingDelay, uint48 effect)
    209
      {
    210
        Access storage access = _roles[roleId].members[account];
    211
    212
        since = access.since;
    213
        (currentDelay, pendingDelay, effect) = access.delay.getFull();
    214
    215
        return (since, currentDelay, pendingDelay, effect);
    216
      }
    217
    218
      /// @inheritdoc IAccessManager
    219
      function hasRole(
    220
        uint64 roleId,
    221
        address account
    222
      ) public view virtual returns (bool isMember, uint32 executionDelay) {
    223
        if (roleId == PUBLIC_ROLE) {
    224
          return (true, 0);
    225
        } else {
    226
          (uint48 hasRoleSince, uint32 currentDelay, , ) = getAccess(roleId, account);
    227
          return (hasRoleSince != 0 && hasRoleSince <= Time.timestamp(), currentDelay);
    228
        }
    229
      }
    230
    231
      // =============================================== ROLE MANAGEMENT ===============================================
    232
      /// @inheritdoc IAccessManager
    233
      function labelRole(uint64 roleId, string calldata label) public virtual onlyAuthorized {
    234
        if (roleId == ADMIN_ROLE || roleId == PUBLIC_ROLE) {
    235
          revert AccessManagerLockedRole(roleId);
    236
        }
    237
        emit RoleLabel(roleId, label);
    238
      }
    239
    240
      /// @inheritdoc IAccessManager
    241
      function grantRole(
    242
        uint64 roleId,
    243
        address account,
    244
        uint32 executionDelay
    245
      ) public virtual onlyAuthorized {
    246
        _grantRole(roleId, account, getRoleGrantDelay(roleId), executionDelay);
    247
      }
    248
    249
      /// @inheritdoc IAccessManager
    250
      function revokeRole(uint64 roleId, address account) public virtual onlyAuthorized {
    251
        _revokeRole(roleId, account);
    252
      }
    253
    254
      /// @inheritdoc IAccessManager
    255
      function renounceRole(uint64 roleId, address callerConfirmation) public virtual {
    256
        if (callerConfirmation != _msgSender()) {
    257
          revert AccessManagerBadConfirmation();
    258
        }
    259
        _revokeRole(roleId, callerConfirmation);
    260
      }
    261
    262
      /// @inheritdoc IAccessManager
    263
      function setRoleAdmin(uint64 roleId, uint64 admin) public virtual onlyAuthorized {
    264
        _setRoleAdmin(roleId, admin);
    265
      }
    266
    267
      /// @inheritdoc IAccessManager
    268
      function setRoleGuardian(uint64 roleId, uint64 guardian) public virtual onlyAuthorized {
    269
        _setRoleGuardian(roleId, guardian);
    270
      }
    271
    272
      /// @inheritdoc IAccessManager
    273
      function setGrantDelay(uint64 roleId, uint32 newDelay) public virtual onlyAuthorized {
    274
        _setGrantDelay(roleId, newDelay);
    275
      }
    276
    277
      /**
    278
       * @dev Internal version of {grantRole} without access control. Returns true if the role was newly granted.
    279
       *
    280
       * Emits a {RoleGranted} event.
    281
       */
    282
      function _grantRole(
    283
        uint64 roleId,
    284
        address account,
    285
        uint32 grantDelay,
    286
        uint32 executionDelay
    287
      ) internal virtual returns (bool) {
    288
        if (roleId == PUBLIC_ROLE) {
    289
          revert AccessManagerLockedRole(roleId);
    290
        }
    291
    292
        bool newMember = _roles[roleId].members[account].since == 0;
    293
        uint48 since;
    294
    295
        if (newMember) {
    296
          since = Time.timestamp() + grantDelay;
    297
          _roles[roleId].members[account] = Access({since: since, delay: executionDelay.toDelay()});
    298
        } else {
    299
          // No setback here. Value can be reset by doing revoke + grant, effectively allowing the admin to perform
    300
          // any change to the execution delay within the duration of the role admin delay.
    301
          (_roles[roleId].members[account].delay, since) = _roles[roleId]
    302
            .members[account]
    303
            .delay
    304
            .withUpdate(executionDelay, 0);
    305
        }
    306
    307
        emit RoleGranted(roleId, account, executionDelay, since, newMember);
    308
        return newMember;
    309
      }
    310
    311
      /**
    312
       * @dev Internal version of {revokeRole} without access control. This logic is also used by {renounceRole}.
    313
       * Returns true if the role was previously granted.
    314
       *
    315
       * Emits a {RoleRevoked} event if the account had the role.
    316
       */
    317
      function _revokeRole(uint64 roleId, address account) internal virtual returns (bool) {
    318
        if (roleId == PUBLIC_ROLE) {
    319
          revert AccessManagerLockedRole(roleId);
    320
        }
    321
    322
        if (_roles[roleId].members[account].since == 0) {
    323
          return false;
    324
        }
    325
    326
        delete _roles[roleId].members[account];
    327
    328
        emit RoleRevoked(roleId, account);
    329
        return true;
    330
      }
    331
    332
      /**
    333
       * @dev Internal version of {setRoleAdmin} without access control.
    334
       *
    335
       * Emits a {RoleAdminChanged} event.
    336
       *
    337
       * NOTE: Setting the admin role as the `PUBLIC_ROLE` is allowed, but it will effectively allow
    338
       * anyone to set grant or revoke such role.
    339
       */
    340
      function _setRoleAdmin(uint64 roleId, uint64 admin) internal virtual {
    341
        if (roleId == ADMIN_ROLE || roleId == PUBLIC_ROLE) {
    342
          revert AccessManagerLockedRole(roleId);
    343
        }
    344
    345
        _roles[roleId].admin = admin;
    346
    347
        emit RoleAdminChanged(roleId, admin);
    348
      }
    349
    350
      /**
    351
       * @dev Internal version of {setRoleGuardian} without access control.
    352
       *
    353
       * Emits a {RoleGuardianChanged} event.
    354
       *
    355
       * NOTE: Setting the guardian role as the `PUBLIC_ROLE` is allowed, but it will effectively allow
    356
       * anyone to cancel any scheduled operation for such role.
    357
       */
    358
      function _setRoleGuardian(uint64 roleId, uint64 guardian) internal virtual {
    359
        if (roleId == ADMIN_ROLE || roleId == PUBLIC_ROLE) {
    360
          revert AccessManagerLockedRole(roleId);
    361
        }
    362
    363
        _roles[roleId].guardian = guardian;
    364
    365
        emit RoleGuardianChanged(roleId, guardian);
    366
      }
    367
    368
      /**
    369
       * @dev Internal version of {setGrantDelay} without access control.
    370
       *
    371
       * Emits a {RoleGrantDelayChanged} event.
    372
       */
    373
      function _setGrantDelay(uint64 roleId, uint32 newDelay) internal virtual {
    374
        if (roleId == PUBLIC_ROLE) {
    375
          revert AccessManagerLockedRole(roleId);
    376
        }
    377
    378
        uint48 effect;
    379
        (_roles[roleId].grantDelay, effect) = _roles[roleId].grantDelay.withUpdate(
    380
          newDelay,
    381
          minSetback()
    382
        );
    383
    384
        emit RoleGrantDelayChanged(roleId, newDelay, effect);
    385
      }
    386
    387
      // ============================================= FUNCTION MANAGEMENT ==============================================
    388
      /// @inheritdoc IAccessManager
    389
      function setTargetFunctionRole(
    390
        address target,
    391
        bytes4[] calldata selectors,
    392
        uint64 roleId
    393
      ) public virtual onlyAuthorized {
    394
        for (uint256 i = 0; i < selectors.length; ++i) {
    395
          _setTargetFunctionRole(target, selectors[i], roleId);
    396
        }
    397
      }
    398
    399
      /**
    400
       * @dev Internal version of {setTargetFunctionRole} without access control.
    401
       *
    402
       * Emits a {TargetFunctionRoleUpdated} event.
    403
       */
    404
      function _setTargetFunctionRole(address target, bytes4 selector, uint64 roleId) internal virtual {
    405
        _targets[target].allowedRoles[selector] = roleId;
    406
        emit TargetFunctionRoleUpdated(target, selector, roleId);
    407
      }
    408
    409
      /// @inheritdoc IAccessManager
    410
      function setTargetAdminDelay(address target, uint32 newDelay) public virtual onlyAuthorized {
    411
        _setTargetAdminDelay(target, newDelay);
    412
      }
    413
    414
      /**
    415
       * @dev Internal version of {setTargetAdminDelay} without access control.
    416
       *
    417
       * Emits a {TargetAdminDelayUpdated} event.
    418
       */
    419
      function _setTargetAdminDelay(address target, uint32 newDelay) internal virtual {
    420
        uint48 effect;
    421
        (_targets[target].adminDelay, effect) = _targets[target].adminDelay.withUpdate(
    422
          newDelay,
    423
          minSetback()
    424
        );
    425
    426
        emit TargetAdminDelayUpdated(target, newDelay, effect);
    427
      }
    428
    429
      // =============================================== MODE MANAGEMENT ================================================
    430
      /// @inheritdoc IAccessManager
    431
      function setTargetClosed(address target, bool closed) public virtual onlyAuthorized {
    432
        _setTargetClosed(target, closed);
    433
      }
    434
    435
      /**
    436
       * @dev Set the closed flag for a contract. This is an internal setter with no access restrictions.
    437
       *
    438
       * Emits a {TargetClosed} event.
    439
       */
    440
      function _setTargetClosed(address target, bool closed) internal virtual {
    441
        _targets[target].closed = closed;
    442
        emit TargetClosed(target, closed);
    443
      }
    444
    445
      // ============================================== DELAYED OPERATIONS ==============================================
    446
      /// @inheritdoc IAccessManager
    447
      function getSchedule(bytes32 id) public view virtual returns (uint48) {
    448
        uint48 timepoint = _schedules[id].timepoint;
    449
        return _isExpired(timepoint) ? 0 : timepoint;
    450
      }
    451
    452
      /// @inheritdoc IAccessManager
    453
      function getNonce(bytes32 id) public view virtual returns (uint32) {
    454
        return _schedules[id].nonce;
    455
      }
    456
    457
      /// @inheritdoc IAccessManager
    458
      function schedule(
    459
        address target,
    460
        bytes calldata data,
    461
        uint48 when
    462
      ) public virtual returns (bytes32 operationId, uint32 nonce) {
    463
        address caller = _msgSender();
    464
    465
        // Fetch restrictions that apply to the caller on the targeted function
    466
        (, uint32 setback) = _canCallExtended(caller, target, data);
    467
    468
        uint48 minWhen = Time.timestamp() + setback;
    469
    470
        // If call with delay is not authorized, or if requested timing is too soon, revert
    471
        if (setback == 0 || (when > 0 && when < minWhen)) {
    472
          revert AccessManagerUnauthorizedCall(caller, target, _checkSelector(data));
    473
        }
    474
    475
        // Reuse variable due to stack too deep
    476
        when = uint48(Math.max(when, minWhen)); // cast is safe: both inputs are uint48
    477
    478
        // If caller is authorised, schedule operation
    479
        operationId = hashOperation(caller, target, data);
    480
    481
        _checkNotScheduled(operationId);
    482
    483
        unchecked {
    484
          // It's not feasible to overflow the nonce in less than 1000 years
    485
          nonce = _schedules[operationId].nonce + 1;
    486
        }
    487
        _schedules[operationId].timepoint = when;
    488
        _schedules[operationId].nonce = nonce;
    489
        emit OperationScheduled(operationId, nonce, when, caller, target, data);
    490
    491
        // Using named return values because otherwise we get stack too deep
    492
      }
    493
    494
      /**
    495
       * @dev Reverts if the operation is currently scheduled and has not expired.
    496
       *
    497
       * NOTE: This function was introduced due to stack too deep errors in schedule.
    498
       */
    499
      function _checkNotScheduled(bytes32 operationId) private view {
    500
        uint48 prevTimepoint = _schedules[operationId].timepoint;
    501
        if (prevTimepoint != 0 && !_isExpired(prevTimepoint)) {
    502
          revert AccessManagerAlreadyScheduled(operationId);
    503
        }
    504
      }
    505
    506
      /// @inheritdoc IAccessManager
    507
      // Reentrancy is not an issue because permissions are checked on msg.sender. Additionally,
    508
      // _consumeScheduledOp guarantees a scheduled operation is only executed once.
    509
      // slither-disable-next-line reentrancy-no-eth
    510
      function execute(address target, bytes calldata data) public payable virtual returns (uint32) {
    511
        address caller = _msgSender();
    512
    513
        // Fetch restrictions that apply to the caller on the targeted function
    514
        (bool immediate, uint32 setback) = _canCallExtended(caller, target, data);
    515
    516
        // If call is not authorized, revert
    517
        if (!immediate && setback == 0) {
    518
          revert AccessManagerUnauthorizedCall(caller, target, _checkSelector(data));
    519
        }
    520
    521
        bytes32 operationId = hashOperation(caller, target, data);
    522
        uint32 nonce;
    523
    524
        // If caller is authorised, check operation was scheduled early enough
    525
        // Consume an available schedule even if there is no currently enforced delay
    526
        if (setback != 0 || getSchedule(operationId) != 0) {
    527
          nonce = _consumeScheduledOp(operationId);
    528
        }
    529
    530
        // Mark the target and selector as authorised
    531
        bytes32 executionIdBefore = _executionId;
    532
        _executionId = _hashExecutionId(target, _checkSelector(data));
    533
    534
        // Perform call
    535
        Address.functionCallWithValue(target, data, msg.value);
    536
    537
        // Reset execute identifier
    538
        _executionId = executionIdBefore;
    539
    540
        return nonce;
    541
      }
    542
    543
      /// @inheritdoc IAccessManager
    544
      function cancel(
    545
        address caller,
    546
        address target,
    547
        bytes calldata data
    548
      ) public virtual returns (uint32) {
    549
        address msgsender = _msgSender();
    550
        bytes4 selector = _checkSelector(data);
    551
    552
        bytes32 operationId = hashOperation(caller, target, data);
    553
        if (_schedules[operationId].timepoint == 0) {
    554
          revert AccessManagerNotScheduled(operationId);
    555
        } else if (caller != msgsender) {
    556
          // calls can only be canceled by the account that scheduled them, a global admin, or by a guardian of the required role.
    557
          (bool isAdmin, ) = hasRole(ADMIN_ROLE, msgsender);
    558
          (bool isGuardian, ) = hasRole(
    559
            getRoleGuardian(getTargetFunctionRole(target, selector)),
    560
            msgsender
    561
          );
    562
          if (!isAdmin && !isGuardian) {
    563
            revert AccessManagerUnauthorizedCancel(msgsender, caller, target, selector);
    564
          }
    565
        }
    566
    567
        delete _schedules[operationId].timepoint; // reset the timepoint, keep the nonce
    568
        uint32 nonce = _schedules[operationId].nonce;
    569
        emit OperationCanceled(operationId, nonce);
    570
    571
        return nonce;
    572
      }
    573
    574
      /// @inheritdoc IAccessManager
    575
      function consumeScheduledOp(address caller, bytes calldata data) public virtual {
    576
        address target = _msgSender();
    577
        if (
    578
          IAccessManaged(target).isConsumingScheduledOp() !=
    579
          IAccessManaged.isConsumingScheduledOp.selector
    580
        ) {
    581
          revert AccessManagerUnauthorizedConsume(target);
    582
        }
    583
        _consumeScheduledOp(hashOperation(caller, target, data));
    584
      }
    585
    586
      /**
    587
       * @dev Internal variant of {consumeScheduledOp} that operates on bytes32 operationId.
    588
       *
    589
       * Returns the nonce of the scheduled operation that is consumed.
    590
       */
    591
      function _consumeScheduledOp(bytes32 operationId) internal virtual returns (uint32) {
    592
        uint48 timepoint = _schedules[operationId].timepoint;
    593
        uint32 nonce = _schedules[operationId].nonce;
    594
    595
        if (timepoint == 0) {
    596
          revert AccessManagerNotScheduled(operationId);
    597
        } else if (timepoint > Time.timestamp()) {
    598
          revert AccessManagerNotReady(operationId);
    599
        } else if (_isExpired(timepoint)) {
    600
          revert AccessManagerExpired(operationId);
    601
        }
    602
    603
        delete _schedules[operationId].timepoint; // reset the timepoint, keep the nonce
    604
        emit OperationExecuted(operationId, nonce);
    605
    606
        return nonce;
    607
      }
    608
    609
      /// @inheritdoc IAccessManager
    610
      function hashOperation(
    611
        address caller,
    612
        address target,
    613
        bytes calldata data
    614
      ) public view virtual returns (bytes32) {
    615
        return keccak256(abi.encode(caller, target, data));
    616
      }
    617
    618
      // ==================================================== OTHERS ====================================================
    619
      /// @inheritdoc IAccessManager
    620
      function updateAuthority(address target, address newAuthority) public virtual onlyAuthorized {
    621
        IAccessManaged(target).setAuthority(newAuthority);
    622
      }
    623
    624
      // ================================================= ADMIN LOGIC ==================================================
    625
      /**
    626
       * @dev Check if the current call is authorized according to admin and roles logic.
    627
       *
    628
       * WARNING: Carefully review the considerations of {AccessManaged-restricted} since they apply to this modifier.
    629
       */
    630
      function _checkAuthorized() private {
    631
        address caller = _msgSender();
    632
        (bool immediate, uint32 delay) = _canCallSelf(caller, _msgData());
    633
        if (!immediate) {
    634
          if (delay == 0) {
    635
            (, uint64 requiredRole, ) = _getAdminRestrictions(_msgData());
    636
            revert AccessManagerUnauthorizedAccount(caller, requiredRole);
    637
          } else {
    638
            _consumeScheduledOp(hashOperation(caller, address(this), _msgData()));
    639
          }
    640
        }
    641
      }
    642
    643
      /**
    644
       * @dev Get the admin restrictions of a given function call based on the function and arguments involved.
    645
       *
    646
       * Returns:
    647
       * - bool restricted: does this data match a restricted operation
    648
       * - uint64: which role is this operation restricted to
    649
       * - uint32: minimum delay to enforce for that operation (max between operation's delay and admin's execution delay)
    650
       */
    651
      function _getAdminRestrictions(
    652
        bytes calldata data
    653
      ) private view returns (bool adminRestricted, uint64 roleAdminId, uint32 executionDelay) {
    654
        if (data.length < 4) {
    655
          return (false, 0, 0);
    656
        }
    657
    658
        bytes4 selector = _checkSelector(data);
    659
    660
        // Restricted to ADMIN with no delay beside any execution delay the caller may have
    661
        if (
    662
          selector == this.labelRole.selector ||
    663
          selector == this.setRoleAdmin.selector ||
    664
          selector == this.setRoleGuardian.selector ||
    665
          selector == this.setGrantDelay.selector ||
    666
          selector == this.setTargetAdminDelay.selector
    667
        ) {
    668
          return (true, ADMIN_ROLE, 0);
    669
        }
    670
    671
        // Restricted to ADMIN with the admin delay corresponding to the target
    672
        if (
    673
          selector == this.updateAuthority.selector ||
    674
          selector == this.setTargetClosed.selector ||
    675
          selector == this.setTargetFunctionRole.selector
    676
        ) {
    677
          // First argument is a target.
    678
          address target = abi.decode(data[0x04:0x24], (address));
    679
          uint32 delay = getTargetAdminDelay(target);
    680
          return (true, ADMIN_ROLE, delay);
    681
        }
    682
    683
        // Restricted to that role's admin with no delay beside any execution delay the caller may have.
    684
        if (selector == this.grantRole.selector || selector == this.revokeRole.selector) {
    685
          // First argument is a roleId.
    686
          uint64 roleId = abi.decode(data[0x04:0x24], (uint64));
    687
          return (true, getRoleAdmin(roleId), 0);
    688
        }
    689
    690
        return (false, getTargetFunctionRole(address(this), selector), 0);
    691
      }
    692
    693
      // =================================================== HELPERS ====================================================
    694
      /**
    695
       * @dev An extended version of {canCall} for internal usage that checks {_canCallSelf}
    696
       * when the target is this contract.
    697
       *
    698
       * Returns:
    699
       * - bool immediate: whether the operation can be executed immediately (with no delay)
    700
       * - uint32 delay: the execution delay
    701
       */
    702
      function _canCallExtended(
    703
        address caller,
    704
        address target,
    705
        bytes calldata data
    706
      ) private view returns (bool immediate, uint32 delay) {
    707
        if (target == address(this)) {
    708
          return _canCallSelf(caller, data);
    709
        } else {
    710
          return data.length < 4 ? (false, 0) : canCall(caller, target, _checkSelector(data));
    711
        }
    712
      }
    713
    714
      /**
    715
       * @dev A version of {canCall} that checks for restrictions in this contract.
    716
       */
    717
      function _canCallSelf(
    718
        address caller,
    719
        bytes calldata data
    720
      ) private view returns (bool immediate, uint32 delay) {
    721
        if (data.length < 4) {
    722
          return (false, 0);
    723
        }
    724
    725
        if (caller == address(this)) {
    726
          // Caller is AccessManager, this means the call was sent through {execute} and it already checked
    727
          // permissions. We verify that the call "identifier", which is set during {execute}, is correct.
    728
          return (_isExecuting(address(this), _checkSelector(data)), 0);
    729
        }
    730
    731
        (bool adminRestricted, uint64 roleId, uint32 operationDelay) = _getAdminRestrictions(data);
    732
    733
        // isTargetClosed apply to non-admin-restricted function
    734
        if (!adminRestricted && isTargetClosed(address(this))) {
    735
          return (false, 0);
    736
        }
    737
    738
        (bool inRole, uint32 executionDelay) = hasRole(roleId, caller);
    739
        if (!inRole) {
    740
          return (false, 0);
    741
        }
    742
    743
        // downcast is safe because both options are uint32
    744
        delay = uint32(Math.max(operationDelay, executionDelay));
    745
        return (delay == 0, delay);
    746
      }
    747
    748
      /**
    749
       * @dev Returns true if a call with `target` and `selector` is being executed via {executed}.
    750
       */
    751
      function _isExecuting(address target, bytes4 selector) private view returns (bool) {
    752
        return _executionId == _hashExecutionId(target, selector);
    753
      }
    754
    755
      /**
    756
       * @dev Returns true if a schedule timepoint is past its expiration deadline.
    757
       */
    758
      function _isExpired(uint48 timepoint) private view returns (bool) {
    759
        return timepoint + expiration() <= Time.timestamp();
    760
      }
    761
    762
      /**
    763
       * @dev Extracts the selector from calldata. Panics if data is not at least 4 bytes
    764
       */
    765
      function _checkSelector(bytes calldata data) private pure returns (bytes4) {
    766
        return bytes4(data[0:4]);
    767
      }
    768
    769
      /**
    770
       * @dev Hashing function for execute protection
    771
       */
    772
      function _hashExecutionId(address target, bytes4 selector) private pure returns (bytes32) {
    773
        return keccak256(abi.encode(target, selector));
    774
      }
    775
    }
    776
    100.0% src/dependencies/openzeppelin/Address.sol
    Lines covered: 2 / 2 (100.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.4.0) (utils/Address.sol)
    3
    4
    pragma solidity ^0.8.20;
    5
    6
    import {Errors} from './Errors.sol';
    7
    8
    /**
    9
     * @dev Collection of functions related to the address type
    10
     */
    11
    library Address {
    12
      /**
    13
       * @dev There's no code at `target` (it is not a contract).
    14
       */
    15
      error AddressEmptyCode(address target);
    16
    17
      /**
    18
       * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
    19
       * `recipient`, forwarding all available gas and reverting on errors.
    20
       *
    21
       * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
    22
       * of certain opcodes, possibly making contracts go over the 2300 gas limit
    23
       * imposed by `transfer`, making them unable to receive funds via
    24
       * `transfer`. {sendValue} removes this limitation.
    25
       *
    26
       * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
    27
       *
    28
       * IMPORTANT: because control is transferred to `recipient`, care must be
    29
       * taken to not create reentrancy vulnerabilities. Consider using
    30
       * {ReentrancyGuard} or the
    31
       * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
    32
       */
    33
      function sendValue(address payable recipient, uint256 amount) internal {
    34
        if (address(this).balance < amount) {
    35
          revert Errors.InsufficientBalance(address(this).balance, amount);
    36
        }
    37
    38
        (bool success, bytes memory returndata) = recipient.call{value: amount}('');
    39
        if (!success) {
    40
          _revert(returndata);
    41
        }
    42
      }
    43
    44
      /**
    45
       * @dev Performs a Solidity function call using a low level `call`. A
    46
       * plain `call` is an unsafe replacement for a function call: use this
    47
       * function instead.
    48
       *
    49
       * If `target` reverts with a revert reason or custom error, it is bubbled
    50
       * up by this function (like regular Solidity function calls). However, if
    51
       * the call reverted with no returned reason, this function reverts with a
    52
       * {Errors.FailedCall} error.
    53
       *
    54
       * Returns the raw returned data. To convert to the expected return value,
    55
       * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
    56
       *
    57
       * Requirements:
    58
       *
    59
       * - `target` must be a contract.
    60
       * - calling `target` with `data` must not revert.
    61
       */
    62
      function functionCall(address target, bytes memory data) internal returns (bytes memory) {
    63
        return functionCallWithValue(target, data, 0);
    64
      }
    65
    66
      /**
    67
       * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
    68
       * but also transferring `value` wei to `target`.
    69
       *
    70
       * Requirements:
    71
       *
    72
       * - the calling contract must have an ETH balance of at least `value`.
    73
       * - the called Solidity function must be `payable`.
    74
       */
    75
      function functionCallWithValue(
    76
        address target,
    77
        bytes memory data,
    78
        uint256 value
    79
      ) internal returns (bytes memory) {
    80
        if (address(this).balance < value) {
    81
          revert Errors.InsufficientBalance(address(this).balance, value);
    82
        }
    83
        (bool success, bytes memory returndata) = target.call{value: value}(data);
    84
        return verifyCallResultFromTarget(target, success, returndata);
    85
      }
    86
    87
      /**
    88
       * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
    89
       * but performing a static call.
    90
       */
    91
      function functionStaticCall(
    92
        address target,
    93
        bytes memory data
    94
      ) internal view returns (bytes memory) {
    95
        (bool success, bytes memory returndata) = target.staticcall(data);
    96
        return verifyCallResultFromTarget(target, success, returndata);
    97
      }
    98
    99
      /**
    100
       * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
    101
       * but performing a delegate call.
    102
       */
    103
      function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
    104
        (bool success, bytes memory returndata) = target.delegatecall(data);
    105
        return verifyCallResultFromTarget(target, success, returndata);
    106
      }
    107
    108
      /**
    109
       * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
    110
       * was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case
    111
       * of an unsuccessful call.
    112
       */
    113
      function verifyCallResultFromTarget(
    114
        address target,
    115
        bool success,
    116
        bytes memory returndata
    117
      ) internal view returns (bytes memory) {
    118
        if (!success) {
    119
          _revert(returndata);
    120
        } else {
    121
          // only check if target is a contract if the call was successful and the return data is empty
    122
          // otherwise we already know that it was a contract
    123
          if (returndata.length == 0 && target.code.length == 0) {
    124
            revert AddressEmptyCode(target);
    125
          }
    126
          return returndata;
    127
        }
    128
      }
    129
    130
      /**
    131
       * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
    132
       * revert reason or with a default {Errors.FailedCall} error.
    133
       */
    134
      function verifyCallResult(
    135
        bool success,
    136
        bytes memory returndata
    137
      ) internal pure returns (bytes memory) {
    138
        if (!success) {
    139
          _revert(returndata);
    140
        } else {
    141
          return returndata;
    142
        }
    143
      }
    144
    145
      /**
    146
       * @dev Reverts with returndata if present. Otherwise reverts with {Errors.FailedCall}.
    147
       */
    148
      function _revert(bytes memory returndata) private pure {
    149
        // Look for revert reason and bubble it up if present
    150
        if (returndata.length > 0) {
    151
          // The easiest way to bubble the revert reason is using memory via assembly
    152
          assembly ('memory-safe') {
    153
            revert(add(returndata, 0x20), mload(returndata))
    154
          }
    155
        } else {
    156
          revert Errors.FailedCall();
    157
        }
    158
      }
    159
    }
    160
    57.0% src/dependencies/openzeppelin/Arrays.sol
    Lines covered: 15 / 26 (57.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.4.0) (utils/Arrays.sol)
    3
    // This file was procedurally generated from scripts/generate/templates/Arrays.js.
    4
    5
    pragma solidity ^0.8.20;
    6
    7
    import {Comparators} from './Comparators.sol';
    8
    import {SlotDerivation} from './SlotDerivation.sol';
    9
    import {StorageSlot} from './StorageSlot.sol';
    10
    import {Math} from './Math.sol';
    11
    12
    /**
    13
     * @dev Collection of functions related to array types.
    14
     */
    15
    library Arrays {
    16
      using SlotDerivation for bytes32;
    17
      using StorageSlot for bytes32;
    18
    19
      /**
    20
       * @dev Sort an array of uint256 (in memory) following the provided comparator function.
    21
       *
    22
       * This function does the sorting "in place", meaning that it overrides the input. The object is returned for
    23
       * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.
    24
       *
    25
       * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the
    26
       * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful
    27
       * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may
    28
       * consume more gas than is available in a block, leading to potential DoS.
    29
       *
    30
       * IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.
    31
       */
    32
      function sort(
    33
        uint256[] memory array,
    34
        function(uint256, uint256) pure returns (bool) comp
    35
      ) internal pure returns (uint256[] memory) {
    36
        _quickSort(_begin(array), _end(array), comp);
    37
        return array;
    38
      }
    39
    40
      /**
    41
       * @dev Variant of {sort} that sorts an array of uint256 in increasing order.
    42
       */
    43
      function sort(uint256[] memory array) internal pure returns (uint256[] memory) {
    44
        sort(array, Comparators.lt);
    45
        return array;
    46
      }
    47
    48
      /**
    49
       * @dev Sort an array of address (in memory) following the provided comparator function.
    50
       *
    51
       * This function does the sorting "in place", meaning that it overrides the input. The object is returned for
    52
       * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.
    53
       *
    54
       * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the
    55
       * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful
    56
       * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may
    57
       * consume more gas than is available in a block, leading to potential DoS.
    58
       *
    59
       * IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.
    60
       */
    61
      function sort(
    62
        address[] memory array,
    63
        function(address, address) pure returns (bool) comp
    64
      ) internal pure returns (address[] memory) {
    65
        sort(_castToUint256Array(array), _castToUint256Comp(comp));
    66
        return array;
    67
      }
    68
    69
      /**
    70
       * @dev Variant of {sort} that sorts an array of address in increasing order.
    71
       */
    72
      function sort(address[] memory array) internal pure returns (address[] memory) {
    73
        sort(_castToUint256Array(array), Comparators.lt);
    74
        return array;
    75
      }
    76
    77
      /**
    78
       * @dev Sort an array of bytes32 (in memory) following the provided comparator function.
    79
       *
    80
       * This function does the sorting "in place", meaning that it overrides the input. The object is returned for
    81
       * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.
    82
       *
    83
       * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the
    84
       * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful
    85
       * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may
    86
       * consume more gas than is available in a block, leading to potential DoS.
    87
       *
    88
       * IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.
    89
       */
    90
      function sort(
    91
        bytes32[] memory array,
    92
        function(bytes32, bytes32) pure returns (bool) comp
    93
      ) internal pure returns (bytes32[] memory) {
    94
        sort(_castToUint256Array(array), _castToUint256Comp(comp));
    95
        return array;
    96
      }
    97
    98
      /**
    99
       * @dev Variant of {sort} that sorts an array of bytes32 in increasing order.
    100
       */
    101
      function sort(bytes32[] memory array) internal pure returns (bytes32[] memory) {
    102
        sort(_castToUint256Array(array), Comparators.lt);
    103
        return array;
    104
      }
    105
    106
      /**
    107
       * @dev Performs a quick sort of a segment of memory. The segment sorted starts at `begin` (inclusive), and stops
    108
       * at end (exclusive). Sorting follows the `comp` comparator.
    109
       *
    110
       * Invariant: `begin <= end`. This is the case when initially called by {sort} and is preserved in subcalls.
    111
       *
    112
       * IMPORTANT: Memory locations between `begin` and `end` are not validated/zeroed. This function should
    113
       * be used only if the limits are within a memory array.
    114
       */
    115
      function _quickSort(
    116
        uint256 begin,
    117
        uint256 end,
    118
        function(uint256, uint256) pure returns (bool) comp
    119
      ) private pure {
    120
        unchecked {
    121
          if (end - begin < 0x40) return;
    122
    123
          // Use first element as pivot
    124
          uint256 pivot = _mload(begin);
    125
          // Position where the pivot should be at the end of the loop
    126
          uint256 pos = begin;
    127
    128
          for (uint256 it = begin + 0x20; it < end; it += 0x20) {
    129
            if (comp(_mload(it), pivot)) {
    130
              // If the value stored at the iterator's position comes before the pivot, we increment the
    131
              // position of the pivot and move the value there.
    132
              pos += 0x20;
    133
              _swap(pos, it);
    134
            }
    135
          }
    136
    137
          _swap(begin, pos); // Swap pivot into place
    138
          _quickSort(begin, pos, comp); // Sort the left side of the pivot
    139
          _quickSort(pos + 0x20, end, comp); // Sort the right side of the pivot
    140
        }
    141
      }
    142
    143
      /**
    144
       * @dev Pointer to the memory location of the first element of `array`.
    145
       */
    146
      function _begin(uint256[] memory array) private pure returns (uint256 ptr) {
    147
        assembly ('memory-safe') {
    148
          ptr := add(array, 0x20)
    149
        }
    150
      }
    151
    152
      /**
    153
       * @dev Pointer to the memory location of the first memory word (32bytes) after `array`. This is the memory word
    154
       * that comes just after the last element of the array.
    155
       */
    156
      function _end(uint256[] memory array) private pure returns (uint256 ptr) {
    157
        unchecked {
    158
          return _begin(array) + array.length * 0x20;
    159
        }
    160
      }
    161
    162
      /**
    163
       * @dev Load memory word (as a uint256) at location `ptr`.
    164
       */
    165
      function _mload(uint256 ptr) private pure returns (uint256 value) {
    166
        assembly {
    167
          value := mload(ptr)
    168
        }
    169
      }
    170
    171
      /**
    172
       * @dev Swaps the elements memory location `ptr1` and `ptr2`.
    173
       */
    174
      function _swap(uint256 ptr1, uint256 ptr2) private pure {
    175
        assembly {
    176
          let value1 := mload(ptr1)
    177
          let value2 := mload(ptr2)
    178
          mstore(ptr1, value2)
    179
          mstore(ptr2, value1)
    180
        }
    181
      }
    182
    183
      /// @dev Helper: low level cast address memory array to uint256 memory array
    184
      function _castToUint256Array(
    185
        address[] memory input
    186
      ) private pure returns (uint256[] memory output) {
    187
        assembly {
    188
          output := input
    189
        }
    190
      }
    191
    192
      /// @dev Helper: low level cast bytes32 memory array to uint256 memory array
    193
      function _castToUint256Array(
    194
        bytes32[] memory input
    195
      ) private pure returns (uint256[] memory output) {
    196
        assembly {
    197
          output := input
    198
        }
    199
      }
    200
    201
      /// @dev Helper: low level cast address comp function to uint256 comp function
    202
      function _castToUint256Comp(
    203
        function(address, address) pure returns (bool) input
    204
      ) private pure returns (function(uint256, uint256) pure returns (bool) output) {
    205
        assembly {
    206
          output := input
    207
        }
    208
      }
    209
    210
      /// @dev Helper: low level cast bytes32 comp function to uint256 comp function
    211
      function _castToUint256Comp(
    212
        function(bytes32, bytes32) pure returns (bool) input
    213
      ) private pure returns (function(uint256, uint256) pure returns (bool) output) {
    214
        assembly {
    215
          output := input
    216
        }
    217
      }
    218
    219
      /**
    220
       * @dev Searches a sorted `array` and returns the first index that contains
    221
       * a value greater or equal to `element`. If no such index exists (i.e. all
    222
       * values in the array are strictly less than `element`), the array length is
    223
       * returned. Time complexity O(log n).
    224
       *
    225
       * NOTE: The `array` is expected to be sorted in ascending order, and to
    226
       * contain no repeated elements.
    227
       *
    228
       * IMPORTANT: Deprecated. This implementation behaves as {lowerBound} but lacks
    229
       * support for repeated elements in the array. The {lowerBound} function should
    230
       * be used instead.
    231
       */
    232
      function findUpperBound(
    233
        uint256[] storage array,
    234
        uint256 element
    235
      ) internal view returns (uint256) {
    236
        uint256 low = 0;
    237
        uint256 high = array.length;
    238
    239
        if (high == 0) {
    240
          return 0;
    241
        }
    242
    243
        while (low < high) {
    244
          uint256 mid = Math.average(low, high);
    245
    246
          // Note that mid will always be strictly less than high (i.e. it will be a valid array index)
    247
          // because Math.average rounds towards zero (it does integer division with truncation).
    248
          if (unsafeAccess(array, mid).value > element) {
    249
            high = mid;
    250
          } else {
    251
            low = mid + 1;
    252
          }
    253
        }
    254
    255
        // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.
    256
        if (low > 0 && unsafeAccess(array, low - 1).value == element) {
    257
          return low - 1;
    258
        } else {
    259
          return low;
    260
        }
    261
      }
    262
    263
      /**
    264
       * @dev Searches an `array` sorted in ascending order and returns the first
    265
       * index that contains a value greater or equal than `element`. If no such index
    266
       * exists (i.e. all values in the array are strictly less than `element`), the array
    267
       * length is returned. Time complexity O(log n).
    268
       *
    269
       * See C++'s https://en.cppreference.com/w/cpp/algorithm/lower_bound[lower_bound].
    270
       */
    271
      function lowerBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
    272
        uint256 low = 0;
    273
        uint256 high = array.length;
    274
    275
        if (high == 0) {
    276
          return 0;
    277
        }
    278
    279
        while (low < high) {
    280
          uint256 mid = Math.average(low, high);
    281
    282
          // Note that mid will always be strictly less than high (i.e. it will be a valid array index)
    283
          // because Math.average rounds towards zero (it does integer division with truncation).
    284
          if (unsafeAccess(array, mid).value < element) {
    285
            // this cannot overflow because mid < high
    286
            unchecked {
    287
              low = mid + 1;
    288
            }
    289
          } else {
    290
            high = mid;
    291
          }
    292
        }
    293
    294
        return low;
    295
      }
    296
    297
      /**
    298
       * @dev Searches an `array` sorted in ascending order and returns the first
    299
       * index that contains a value strictly greater than `element`. If no such index
    300
       * exists (i.e. all values in the array are strictly less than `element`), the array
    301
       * length is returned. Time complexity O(log n).
    302
       *
    303
       * See C++'s https://en.cppreference.com/w/cpp/algorithm/upper_bound[upper_bound].
    304
       */
    305
      function upperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
    306
        uint256 low = 0;
    307
        uint256 high = array.length;
    308
    309
        if (high == 0) {
    310
          return 0;
    311
        }
    312
    313
        while (low < high) {
    314
          uint256 mid = Math.average(low, high);
    315
    316
          // Note that mid will always be strictly less than high (i.e. it will be a valid array index)
    317
          // because Math.average rounds towards zero (it does integer division with truncation).
    318
          if (unsafeAccess(array, mid).value > element) {
    319
            high = mid;
    320
          } else {
    321
            // this cannot overflow because mid < high
    322
            unchecked {
    323
              low = mid + 1;
    324
            }
    325
          }
    326
        }
    327
    328
        return low;
    329
      }
    330
    331
      /**
    332
       * @dev Same as {lowerBound}, but with an array in memory.
    333
       */
    334
      function lowerBoundMemory(
    335
        uint256[] memory array,
    336
        uint256 element
    337
      ) internal pure returns (uint256) {
    338
        uint256 low = 0;
    339
        uint256 high = array.length;
    340
    341
        if (high == 0) {
    342
          return 0;
    343
        }
    344
    345
        while (low < high) {
    346
          uint256 mid = Math.average(low, high);
    347
    348
          // Note that mid will always be strictly less than high (i.e. it will be a valid array index)
    349
          // because Math.average rounds towards zero (it does integer division with truncation).
    350
          if (unsafeMemoryAccess(array, mid) < element) {
    351
            // this cannot overflow because mid < high
    352
            unchecked {
    353
              low = mid + 1;
    354
            }
    355
          } else {
    356
            high = mid;
    357
          }
    358
        }
    359
    360
        return low;
    361
      }
    362
    363
      /**
    364
       * @dev Same as {upperBound}, but with an array in memory.
    365
       */
    366
      function upperBoundMemory(
    367
        uint256[] memory array,
    368
        uint256 element
    369
      ) internal pure returns (uint256) {
    370
        uint256 low = 0;
    371
        uint256 high = array.length;
    372
    373
        if (high == 0) {
    374
          return 0;
    375
        }
    376
    377
        while (low < high) {
    378
          uint256 mid = Math.average(low, high);
    379
    380
          // Note that mid will always be strictly less than high (i.e. it will be a valid array index)
    381
          // because Math.average rounds towards zero (it does integer division with truncation).
    382
          if (unsafeMemoryAccess(array, mid) > element) {
    383
            high = mid;
    384
          } else {
    385
            // this cannot overflow because mid < high
    386
            unchecked {
    387
              low = mid + 1;
    388
            }
    389
          }
    390
        }
    391
    392
        return low;
    393
      }
    394
    395
      /**
    396
       * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
    397
       *
    398
       * WARNING: Only use if you are certain `pos` is lower than the array length.
    399
       */
    400
      function unsafeAccess(
    401
        address[] storage arr,
    402
        uint256 pos
    403
      ) internal pure returns (StorageSlot.AddressSlot storage) {
    404
        bytes32 slot;
    405
        assembly ('memory-safe') {
    406
          slot := arr.slot
    407
        }
    408
        return slot.deriveArray().offset(pos).getAddressSlot();
    409
      }
    410
    411
      /**
    412
       * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
    413
       *
    414
       * WARNING: Only use if you are certain `pos` is lower than the array length.
    415
       */
    416
      function unsafeAccess(
    417
        bytes32[] storage arr,
    418
        uint256 pos
    419
      ) internal pure returns (StorageSlot.Bytes32Slot storage) {
    420
        bytes32 slot;
    421
        assembly ('memory-safe') {
    422
          slot := arr.slot
    423
        }
    424
        return slot.deriveArray().offset(pos).getBytes32Slot();
    425
      }
    426
    427
      /**
    428
       * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
    429
       *
    430
       * WARNING: Only use if you are certain `pos` is lower than the array length.
    431
       */
    432
      function unsafeAccess(
    433
        uint256[] storage arr,
    434
        uint256 pos
    435
      ) internal pure returns (StorageSlot.Uint256Slot storage) {
    436
        bytes32 slot;
    437
        assembly ('memory-safe') {
    438
          slot := arr.slot
    439
        }
    440
        return slot.deriveArray().offset(pos).getUint256Slot();
    441
      }
    442
    443
      /**
    444
       * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
    445
       *
    446
       * WARNING: Only use if you are certain `pos` is lower than the array length.
    447
       */
    448
      function unsafeAccess(
    449
        bytes[] storage arr,
    450
        uint256 pos
    451
      ) internal pure returns (StorageSlot.BytesSlot storage) {
    452
        bytes32 slot;
    453
        assembly ('memory-safe') {
    454
          slot := arr.slot
    455
        }
    456
        return slot.deriveArray().offset(pos).getBytesSlot();
    457
      }
    458
    459
      /**
    460
       * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
    461
       *
    462
       * WARNING: Only use if you are certain `pos` is lower than the array length.
    463
       */
    464
      function unsafeAccess(
    465
        string[] storage arr,
    466
        uint256 pos
    467
      ) internal pure returns (StorageSlot.StringSlot storage) {
    468
        bytes32 slot;
    469
        assembly ('memory-safe') {
    470
          slot := arr.slot
    471
        }
    472
        return slot.deriveArray().offset(pos).getStringSlot();
    473
      }
    474
    475
      /**
    476
       * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
    477
       *
    478
       * WARNING: Only use if you are certain `pos` is lower than the array length.
    479
       */
    480
      function unsafeMemoryAccess(
    481
        address[] memory arr,
    482
        uint256 pos
    483
      ) internal pure returns (address res) {
    484
        assembly {
    485
          res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
    486
        }
    487
      }
    488
    489
      /**
    490
       * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
    491
       *
    492
       * WARNING: Only use if you are certain `pos` is lower than the array length.
    493
       */
    494
      function unsafeMemoryAccess(
    495
        bytes32[] memory arr,
    496
        uint256 pos
    497
      ) internal pure returns (bytes32 res) {
    498
        assembly {
    499
          res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
    500
        }
    501
      }
    502
    503
      /**
    504
       * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
    505
       *
    506
       * WARNING: Only use if you are certain `pos` is lower than the array length.
    507
       */
    508
      function unsafeMemoryAccess(
    509
        uint256[] memory arr,
    510
        uint256 pos
    511
      ) internal pure returns (uint256 res) {
    512
        assembly {
    513
          res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
    514
        }
    515
      }
    516
    517
      /**
    518
       * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
    519
       *
    520
       * WARNING: Only use if you are certain `pos` is lower than the array length.
    521
       */
    522
      function unsafeMemoryAccess(
    523
        bytes[] memory arr,
    524
        uint256 pos
    525
      ) internal pure returns (bytes memory res) {
    526
        assembly {
    527
          res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
    528
        }
    529
      }
    530
    531
      /**
    532
       * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
    533
       *
    534
       * WARNING: Only use if you are certain `pos` is lower than the array length.
    535
       */
    536
      function unsafeMemoryAccess(
    537
        string[] memory arr,
    538
        uint256 pos
    539
      ) internal pure returns (string memory res) {
    540
        assembly {
    541
          res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
    542
        }
    543
      }
    544
    545
      /**
    546
       * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
    547
       *
    548
       * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
    549
       */
    550
      function unsafeSetLength(address[] storage array, uint256 len) internal {
    551
        assembly ('memory-safe') {
    552
          sstore(array.slot, len)
    553
        }
    554
      }
    555
    556
      /**
    557
       * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
    558
       *
    559
       * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
    560
       */
    561
      function unsafeSetLength(bytes32[] storage array, uint256 len) internal {
    562
        assembly ('memory-safe') {
    563
          sstore(array.slot, len)
    564
        }
    565
      }
    566
    567
      /**
    568
       * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
    569
       *
    570
       * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
    571
       */
    572
      function unsafeSetLength(uint256[] storage array, uint256 len) internal {
    573
        assembly ('memory-safe') {
    574
          sstore(array.slot, len)
    575
        }
    576
      }
    577
    578
      /**
    579
       * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
    580
       *
    581
       * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
    582
       */
    583
      function unsafeSetLength(bytes[] storage array, uint256 len) internal {
    584
        assembly ('memory-safe') {
    585
          sstore(array.slot, len)
    586
        }
    587
      }
    588
    589
      /**
    590
       * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
    591
       *
    592
       * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
    593
       */
    594
      function unsafeSetLength(string[] storage array, uint256 len) internal {
    595
        assembly ('memory-safe') {
    596
          sstore(array.slot, len)
    597
        }
    598
      }
    599
    }
    600
    100.0% src/dependencies/openzeppelin/AuthorityUtils.sol
    Lines covered: 1 / 1 (100.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.3.0) (access/manager/AuthorityUtils.sol)
    3
    4
    pragma solidity ^0.8.20;
    5
    6
    import {IAuthority} from './IAuthority.sol';
    7
    8
    library AuthorityUtils {
    9
      /**
    10
       * @dev Since `AccessManager` implements an extended IAuthority interface, invoking `canCall` with backwards compatibility
    11
       * for the preexisting `IAuthority` interface requires special care to avoid reverting on insufficient return data.
    12
       * This helper function takes care of invoking `canCall` in a backwards compatible way without reverting.
    13
       */
    14
      function canCallWithDelay(
    15
        address authority,
    16
        address caller,
    17
        address target,
    18
        bytes4 selector
    19
      ) internal view returns (bool immediate, uint32 delay) {
    20
        bytes memory data = abi.encodeCall(IAuthority.canCall, (caller, target, selector));
    21
    22
        assembly ('memory-safe') {
    23
          mstore(0x00, 0x00)
    24
          mstore(0x20, 0x00)
    25
    26
          if staticcall(gas(), authority, add(data, 0x20), mload(data), 0x00, 0x40) {
    27
            immediate := mload(0x00)
    28
            delay := mload(0x20)
    29
    30
            // If delay does not fit in a uint32, return 0 (no delay)
    31
            // equivalent to: if gt(delay, 0xFFFFFFFF) { delay := 0 }
    32
            delay := mul(delay, iszero(shr(32, delay)))
    33
          }
    34
        }
    35
      }
    36
    }
    37
    8.0% src/dependencies/openzeppelin/Bytes.sol
    Lines covered: 2 / 24 (8.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.4.0) (utils/Bytes.sol)
    3
    4
    pragma solidity ^0.8.24;
    5
    6
    import {Math} from './Math.sol';
    7
    8
    /**
    9
     * @dev Bytes operations.
    10
     */
    11
    library Bytes {
    12
      /**
    13
       * @dev Forward search for `s` in `buffer`
    14
       * * If `s` is present in the buffer, returns the index of the first instance
    15
       * * If `s` is not present in the buffer, returns type(uint256).max
    16
       *
    17
       * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf[Javascript's `Array.indexOf`]
    18
       */
    19
      function indexOf(bytes memory buffer, bytes1 s) internal pure returns (uint256) {
    20
        return indexOf(buffer, s, 0);
    21
      }
    22
    23
      /**
    24
       * @dev Forward search for `s` in `buffer` starting at position `pos`
    25
       * * If `s` is present in the buffer (at or after `pos`), returns the index of the next instance
    26
       * * If `s` is not present in the buffer (at or after `pos`), returns type(uint256).max
    27
       *
    28
       * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf[Javascript's `Array.indexOf`]
    29
       */
    30
      function indexOf(bytes memory buffer, bytes1 s, uint256 pos) internal pure returns (uint256) {
    31
        uint256 length = buffer.length;
    32
        for (uint256 i = pos; i < length; ++i) {
    33
          if (bytes1(_unsafeReadBytesOffset(buffer, i)) == s) {
    34
            return i;
    35
          }
    36
        }
    37
        return type(uint256).max;
    38
      }
    39
    40
      /**
    41
       * @dev Backward search for `s` in `buffer`
    42
       * * If `s` is present in the buffer, returns the index of the last instance
    43
       * * If `s` is not present in the buffer, returns type(uint256).max
    44
       *
    45
       * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf[Javascript's `Array.lastIndexOf`]
    46
       */
    47
      function lastIndexOf(bytes memory buffer, bytes1 s) internal pure returns (uint256) {
    48
        return lastIndexOf(buffer, s, type(uint256).max);
    49
      }
    50
    51
      /**
    52
       * @dev Backward search for `s` in `buffer` starting at position `pos`
    53
       * * If `s` is present in the buffer (at or before `pos`), returns the index of the previous instance
    54
       * * If `s` is not present in the buffer (at or before `pos`), returns type(uint256).max
    55
       *
    56
       * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf[Javascript's `Array.lastIndexOf`]
    57
       */
    58
      function lastIndexOf(bytes memory buffer, bytes1 s, uint256 pos) internal pure returns (uint256) {
    59
        unchecked {
    60
          uint256 length = buffer.length;
    61
          for (uint256 i = Math.min(Math.saturatingAdd(pos, 1), length); i > 0; --i) {
    62
            if (bytes1(_unsafeReadBytesOffset(buffer, i - 1)) == s) {
    63
              return i - 1;
    64
            }
    65
          }
    66
          return type(uint256).max;
    67
        }
    68
      }
    69
    70
      /**
    71
       * @dev Copies the content of `buffer`, from `start` (included) to the end of `buffer` into a new bytes object in
    72
       * memory.
    73
       *
    74
       * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice[Javascript's `Array.slice`]
    75
       */
    76
      function slice(bytes memory buffer, uint256 start) internal pure returns (bytes memory) {
    77
        return slice(buffer, start, buffer.length);
    78
      }
    79
    80
      /**
    81
       * @dev Copies the content of `buffer`, from `start` (included) to `end` (excluded) into a new bytes object in
    82
       * memory.
    83
       *
    84
       * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice[Javascript's `Array.slice`]
    85
       */
    86
      function slice(
    87
        bytes memory buffer,
    88
        uint256 start,
    89
        uint256 end
    90
      ) internal pure returns (bytes memory) {
    91
        // sanitize
    92
        uint256 length = buffer.length;
    93
        end = Math.min(end, length);
    94
        start = Math.min(start, end);
    95
    96
        // allocate and copy
    97
        bytes memory result = new bytes(end - start);
    98
        assembly ('memory-safe') {
    99
          mcopy(add(result, 0x20), add(add(buffer, 0x20), start), sub(end, start))
    100
        }
    101
    102
        return result;
    103
      }
    104
    105
      /**
    106
       * @dev Reads a bytes32 from a bytes array without bounds checking.
    107
       *
    108
       * NOTE: making this function internal would mean it could be used with memory unsafe offset, and marking the
    109
       * assembly block as such would prevent some optimizations.
    110
       */
    111
      function _unsafeReadBytesOffset(
    112
        bytes memory buffer,
    113
        uint256 offset
    114
      ) private pure returns (bytes32 value) {
    115
        // This is not memory safe in the general case, but all calls to this private function are within bounds.
    116
        assembly ('memory-safe') {
    117
          value := mload(add(add(buffer, 0x20), offset))
    118
        }
    119
      }
    120
    }
    121
    100.0% src/dependencies/openzeppelin/Comparators.sol
    Lines covered: 1 / 1 (100.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.1.0) (utils/Comparators.sol)
    3
    4
    pragma solidity ^0.8.20;
    5
    6
    /**
    7
     * @dev Provides a set of functions to compare values.
    8
     *
    9
     * _Available since v5.1._
    10
     */
    11
    library Comparators {
    12
      function lt(uint256 a, uint256 b) internal pure returns (bool) {
    13
        return a < b;
    14
      }
    15
    16
      function gt(uint256 a, uint256 b) internal pure returns (bool) {
    17
        return a > b;
    18
      }
    19
    }
    20
    100.0% src/dependencies/openzeppelin/Context.sol
    Lines covered: 7 / 7 (100.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
    3
    4
    pragma solidity ^0.8.20;
    5
    6
    /**
    7
     * @dev Provides information about the current execution context, including the
    8
     * sender of the transaction and its data. While these are generally available
    9
     * via msg.sender and msg.data, they should not be accessed in such a direct
    10
     * manner, since when dealing with meta-transactions the account sending and
    11
     * paying for execution may not be the actual sender (as far as an application
    12
     * is concerned).
    13
     *
    14
     * This contract is only required for intermediate, library-like contracts.
    15
     */
    16
    abstract contract Context {
    17
      function _msgSender() internal view virtual returns (address) {
    18
        return msg.sender;
    19
      }
    20
    21
      function _msgData() internal view virtual returns (bytes calldata) {
    22
        return msg.data;
    23
      }
    24
    25
      function _contextSuffixLength() internal view virtual returns (uint256) {
    26
        return 0;
    27
      }
    28
    }
    29
    100.0% src/dependencies/openzeppelin/ECDSA.sol
    Lines covered: 1 / 1 (100.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/ECDSA.sol)
    3
    4
    pragma solidity ^0.8.20;
    5
    6
    /**
    7
     * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
    8
     *
    9
     * These functions can be used to verify that a message was signed by the holder
    10
     * of the private keys of a given address.
    11
     */
    12
    library ECDSA {
    13
      enum RecoverError {
    14
        NoError,
    15
        InvalidSignature,
    16
        InvalidSignatureLength,
    17
        InvalidSignatureS
    18
      }
    19
    20
      /**
    21
       * @dev The signature derives the `address(0)`.
    22
       */
    23
      error ECDSAInvalidSignature();
    24
    25
      /**
    26
       * @dev The signature has an invalid length.
    27
       */
    28
      error ECDSAInvalidSignatureLength(uint256 length);
    29
    30
      /**
    31
       * @dev The signature has an S value that is in the upper half order.
    32
       */
    33
      error ECDSAInvalidSignatureS(bytes32 s);
    34
    35
      /**
    36
       * @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not
    37
       * return address(0) without also returning an error description. Errors are documented using an enum (error type)
    38
       * and a bytes32 providing additional information about the error.
    39
       *
    40
       * If no error is returned, then the address can be used for verification purposes.
    41
       *
    42
       * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:
    43
       * this function rejects them by requiring the `s` value to be in the lower
    44
       * half order, and the `v` value to be either 27 or 28.
    45
       *
    46
       * IMPORTANT: `hash` _must_ be the result of a hash operation for the
    47
       * verification to be secure: it is possible to craft signatures that
    48
       * recover to arbitrary addresses for non-hashed data. A safe way to ensure
    49
       * this is by receiving a hash of the original message (which may otherwise
    50
       * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.
    51
       *
    52
       * Documentation for signature generation:
    53
       * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
    54
       * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
    55
       */
    56
      function tryRecover(
    57
        bytes32 hash,
    58
        bytes memory signature
    59
      ) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {
    60
        if (signature.length == 65) {
    61
          bytes32 r;
    62
          bytes32 s;
    63
          uint8 v;
    64
          // ecrecover takes the signature parameters, and the only way to get them
    65
          // currently is to use assembly.
    66
          assembly ('memory-safe') {
    67
            r := mload(add(signature, 0x20))
    68
            s := mload(add(signature, 0x40))
    69
            v := byte(0, mload(add(signature, 0x60)))
    70
          }
    71
          return tryRecover(hash, v, r, s);
    72
        } else {
    73
          return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length));
    74
        }
    75
      }
    76
    77
      /**
    78
       * @dev Returns the address that signed a hashed message (`hash`) with
    79
       * `signature`. This address can then be used for verification purposes.
    80
       *
    81
       * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:
    82
       * this function rejects them by requiring the `s` value to be in the lower
    83
       * half order, and the `v` value to be either 27 or 28.
    84
       *
    85
       * IMPORTANT: `hash` _must_ be the result of a hash operation for the
    86
       * verification to be secure: it is possible to craft signatures that
    87
       * recover to arbitrary addresses for non-hashed data. A safe way to ensure
    88
       * this is by receiving a hash of the original message (which may otherwise
    89
       * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.
    90
       */
    91
      function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
    92
        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature);
    93
        _throwError(error, errorArg);
    94
        return recovered;
    95
      }
    96
    97
      /**
    98
       * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
    99
       *
    100
       * See https://eips.ethereum.org/EIPS/eip-2098[ERC-2098 short signatures]
    101
       */
    102
      function tryRecover(
    103
        bytes32 hash,
    104
        bytes32 r,
    105
        bytes32 vs
    106
      ) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {
    107
        unchecked {
    108
          bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
    109
          // We do not check for an overflow here since the shift operation results in 0 or 1.
    110
          uint8 v = uint8((uint256(vs) >> 255) + 27);
    111
          return tryRecover(hash, v, r, s);
    112
        }
    113
      }
    114
    115
      /**
    116
       * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
    117
       */
    118
      function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {
    119
        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs);
    120
        _throwError(error, errorArg);
    121
        return recovered;
    122
      }
    123
    124
      /**
    125
       * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
    126
       * `r` and `s` signature fields separately.
    127
       */
    128
      function tryRecover(
    129
        bytes32 hash,
    130
        uint8 v,
    131
        bytes32 r,
    132
        bytes32 s
    133
      ) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {
    134
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
    135
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
    136
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
    137
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
    138
        //
    139
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
    140
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
    141
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
    142
        // these malleable signatures as well.
    143
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
    144
          return (address(0), RecoverError.InvalidSignatureS, s);
    145
        }
    146
    147
        // If the signature is valid (and not malleable), return the signer address
    148
        address signer = ecrecover(hash, v, r, s);
    149
        if (signer == address(0)) {
    150
          return (address(0), RecoverError.InvalidSignature, bytes32(0));
    151
        }
    152
    153
        return (signer, RecoverError.NoError, bytes32(0));
    154
      }
    155
    156
      /**
    157
       * @dev Overload of {ECDSA-recover} that receives the `v`,
    158
       * `r` and `s` signature fields separately.
    159
       */
    160
      function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {
    161
        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s);
    162
        _throwError(error, errorArg);
    163
        return recovered;
    164
      }
    165
    166
      /**
    167
       * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided.
    168
       */
    169
      function _throwError(RecoverError error, bytes32 errorArg) private pure {
    170
        if (error == RecoverError.NoError) {
    171
          return; // no error: do nothing
    172
        } else if (error == RecoverError.InvalidSignature) {
    173
          revert ECDSAInvalidSignature();
    174
        } else if (error == RecoverError.InvalidSignatureLength) {
    175
          revert ECDSAInvalidSignatureLength(uint256(errorArg));
    176
        } else if (error == RecoverError.InvalidSignatureS) {
    177
          revert ECDSAInvalidSignatureS(errorArg);
    178
        }
    179
      }
    180
    }
    181
    100.0% src/dependencies/openzeppelin/ERC1967Proxy.sol
    Lines covered: 1 / 1 (100.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.2.0) (proxy/ERC1967/ERC1967Proxy.sol)
    3
    4
    pragma solidity ^0.8.22;
    5
    6
    import {Proxy} from './Proxy.sol';
    7
    import {ERC1967Utils} from './ERC1967Utils.sol';
    8
    9
    /**
    10
     * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an
    11
     * implementation address that can be changed. This address is stored in storage in the location specified by
    12
     * https://eips.ethereum.org/EIPS/eip-1967[ERC-1967], so that it doesn't conflict with the storage layout of the
    13
     * implementation behind the proxy.
    14
     */
    15
    contract ERC1967Proxy is Proxy {
    16
      /**
    17
       * @dev Initializes the upgradeable proxy with an initial implementation specified by `implementation`.
    18
       *
    19
       * If `_data` is nonempty, it's used as data in a delegate call to `implementation`. This will typically be an
    20
       * encoded function call, and allows initializing the storage of the proxy like a Solidity constructor.
    21
       *
    22
       * Requirements:
    23
       *
    24
       * - If `data` is empty, `msg.value` must be zero.
    25
       */
    26
      constructor(address implementation, bytes memory _data) payable {
    27
        ERC1967Utils.upgradeToAndCall(implementation, _data);
    28
      }
    29
    30
      /**
    31
       * @dev Returns the current implementation address.
    32
       *
    33
       * TIP: To get this value clients can read directly from the storage slot shown below (specified by ERC-1967) using
    34
       * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
    35
       * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`
    36
       */
    37
      function _implementation() internal view virtual override returns (address) {
    38
        return ERC1967Utils.getImplementation();
    39
      }
    40
    }
    41
    100.0% src/dependencies/openzeppelin/ERC1967Utils.sol
    Lines covered: 3 / 3 (100.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.4.0) (proxy/ERC1967/ERC1967Utils.sol)
    3
    4
    pragma solidity ^0.8.21;
    5
    6
    import {IBeacon} from './IBeacon.sol';
    7
    import {IERC1967} from './IERC1967.sol';
    8
    import {Address} from './Address.sol';
    9
    import {StorageSlot} from './StorageSlot.sol';
    10
    11
    /**
    12
     * @dev This library provides getters and event emitting update functions for
    13
     * https://eips.ethereum.org/EIPS/eip-1967[ERC-1967] slots.
    14
     */
    15
    library ERC1967Utils {
    16
      /**
    17
       * @dev Storage slot with the address of the current implementation.
    18
       * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1.
    19
       */
    20
      // solhint-disable-next-line private-vars-leading-underscore
    21
      bytes32 internal constant IMPLEMENTATION_SLOT =
    22
        0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
    23
    24
      /**
    25
       * @dev The `implementation` of the proxy is invalid.
    26
       */
    27
      error ERC1967InvalidImplementation(address implementation);
    28
    29
      /**
    30
       * @dev The `admin` of the proxy is invalid.
    31
       */
    32
      error ERC1967InvalidAdmin(address admin);
    33
    34
      /**
    35
       * @dev The `beacon` of the proxy is invalid.
    36
       */
    37
      error ERC1967InvalidBeacon(address beacon);
    38
    39
      /**
    40
       * @dev An upgrade function sees `msg.value > 0` that may be lost.
    41
       */
    42
      error ERC1967NonPayable();
    43
    44
      /**
    45
       * @dev Returns the current implementation address.
    46
       */
    47
      function getImplementation() internal view returns (address) {
    48
        return StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value;
    49
      }
    50
    51
      /**
    52
       * @dev Stores a new address in the ERC-1967 implementation slot.
    53
       */
    54
      function _setImplementation(address newImplementation) private {
    55
        if (newImplementation.code.length == 0) {
    56
          revert ERC1967InvalidImplementation(newImplementation);
    57
        }
    58
        StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value = newImplementation;
    59
      }
    60
    61
      /**
    62
       * @dev Performs implementation upgrade with additional setup call if data is nonempty.
    63
       * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected
    64
       * to avoid stuck value in the contract.
    65
       *
    66
       * Emits an {IERC1967-Upgraded} event.
    67
       */
    68
      function upgradeToAndCall(address newImplementation, bytes memory data) internal {
    69
        _setImplementation(newImplementation);
    70
        emit IERC1967.Upgraded(newImplementation);
    71
    72
        if (data.length > 0) {
    73
          Address.functionDelegateCall(newImplementation, data);
    74
        } else {
    75
          _checkNonPayable();
    76
        }
    77
      }
    78
    79
      /**
    80
       * @dev Storage slot with the admin of the contract.
    81
       * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1.
    82
       */
    83
      // solhint-disable-next-line private-vars-leading-underscore
    84
      bytes32 internal constant ADMIN_SLOT =
    85
        0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
    86
    87
      /**
    88
       * @dev Returns the current admin.
    89
       *
    90
       * TIP: To get this value clients can read directly from the storage slot shown below (specified by ERC-1967) using
    91
       * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
    92
       * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`
    93
       */
    94
      function getAdmin() internal view returns (address) {
    95
        return StorageSlot.getAddressSlot(ADMIN_SLOT).value;
    96
      }
    97
    98
      /**
    99
       * @dev Stores a new address in the ERC-1967 admin slot.
    100
       */
    101
      function _setAdmin(address newAdmin) private {
    102
        if (newAdmin == address(0)) {
    103
          revert ERC1967InvalidAdmin(address(0));
    104
        }
    105
        StorageSlot.getAddressSlot(ADMIN_SLOT).value = newAdmin;
    106
      }
    107
    108
      /**
    109
       * @dev Changes the admin of the proxy.
    110
       *
    111
       * Emits an {IERC1967-AdminChanged} event.
    112
       */
    113
      function changeAdmin(address newAdmin) internal {
    114
        emit IERC1967.AdminChanged(getAdmin(), newAdmin);
    115
        _setAdmin(newAdmin);
    116
      }
    117
    118
      /**
    119
       * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
    120
       * This is the keccak-256 hash of "eip1967.proxy.beacon" subtracted by 1.
    121
       */
    122
      // solhint-disable-next-line private-vars-leading-underscore
    123
      bytes32 internal constant BEACON_SLOT =
    124
        0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;
    125
    126
      /**
    127
       * @dev Returns the current beacon.
    128
       */
    129
      function getBeacon() internal view returns (address) {
    130
        return StorageSlot.getAddressSlot(BEACON_SLOT).value;
    131
      }
    132
    133
      /**
    134
       * @dev Stores a new beacon in the ERC-1967 beacon slot.
    135
       */
    136
      function _setBeacon(address newBeacon) private {
    137
        if (newBeacon.code.length == 0) {
    138
          revert ERC1967InvalidBeacon(newBeacon);
    139
        }
    140
    141
        StorageSlot.getAddressSlot(BEACON_SLOT).value = newBeacon;
    142
    143
        address beaconImplementation = IBeacon(newBeacon).implementation();
    144
        if (beaconImplementation.code.length == 0) {
    145
          revert ERC1967InvalidImplementation(beaconImplementation);
    146
        }
    147
      }
    148
    149
      /**
    150
       * @dev Change the beacon and trigger a setup call if data is nonempty.
    151
       * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected
    152
       * to avoid stuck value in the contract.
    153
       *
    154
       * Emits an {IERC1967-BeaconUpgraded} event.
    155
       *
    156
       * CAUTION: Invoking this function has no effect on an instance of {BeaconProxy} since v5, since
    157
       * it uses an immutable beacon without looking at the value of the ERC-1967 beacon slot for
    158
       * efficiency.
    159
       */
    160
      function upgradeBeaconToAndCall(address newBeacon, bytes memory data) internal {
    161
        _setBeacon(newBeacon);
    162
        emit IERC1967.BeaconUpgraded(newBeacon);
    163
    164
        if (data.length > 0) {
    165
          Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);
    166
        } else {
    167
          _checkNonPayable();
    168
        }
    169
      }
    170
    171
      /**
    172
       * @dev Reverts if `msg.value` is not zero. It can be used to avoid `msg.value` stuck in the contract
    173
       * if an upgrade doesn't perform an initialization call.
    174
       */
    175
      function _checkNonPayable() private {
    176
        if (msg.value > 0) {
    177
          revert ERC1967NonPayable();
    178
        }
    179
      }
    180
    }
    181
    17.0% src/dependencies/openzeppelin/ERC20.sol
    Lines covered: 3 / 17 (17.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/ERC20.sol)
    3
    4
    pragma solidity ^0.8.20;
    5
    6
    import {IERC20} from './IERC20.sol';
    7
    import {IERC20Metadata} from './IERC20Metadata.sol';
    8
    import {Context} from './Context.sol';
    9
    import {IERC20Errors} from './IERC20Errors.sol';
    10
    11
    /**
    12
     * @dev Implementation of the {IERC20} interface.
    13
     *
    14
     * This implementation is agnostic to the way tokens are created. This means
    15
     * that a supply mechanism has to be added in a derived contract using {_mint}.
    16
     *
    17
     * TIP: For a detailed writeup see our guide
    18
     * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
    19
     * to implement supply mechanisms].
    20
     *
    21
     * The default value of {decimals} is 18. To change this, you should override
    22
     * this function so it returns a different value.
    23
     *
    24
     * We have followed general OpenZeppelin Contracts guidelines: functions revert
    25
     * instead returning `false` on failure. This behavior is nonetheless
    26
     * conventional and does not conflict with the expectations of ERC-20
    27
     * applications.
    28
     */
    29
    abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
    30
      mapping(address account => uint256) private _balances;
    31
    32
      mapping(address account => mapping(address spender => uint256)) private _allowances;
    33
    34
      uint256 private _totalSupply;
    35
    36
      string private _name;
    37
      string private _symbol;
    38
    39
      /**
    40
       * @dev Sets the values for {name} and {symbol}.
    41
       *
    42
       * Both values are immutable: they can only be set once during construction.
    43
       */
    44
      constructor(string memory name_, string memory symbol_) {
    45
        _name = name_;
    46
        _symbol = symbol_;
    47
      }
    48
    49
      /**
    50
       * @dev Returns the name of the token.
    51
       */
    52
      function name() public view virtual returns (string memory) {
    53
        return _name;
    54
      }
    55
    56
      /**
    57
       * @dev Returns the symbol of the token, usually a shorter version of the
    58
       * name.
    59
       */
    60
      function symbol() public view virtual returns (string memory) {
    61
        return _symbol;
    62
      }
    63
    64
      /**
    65
       * @dev Returns the number of decimals used to get its user representation.
    66
       * For example, if `decimals` equals `2`, a balance of `505` tokens should
    67
       * be displayed to a user as `5.05` (`505 / 10 ** 2`).
    68
       *
    69
       * Tokens usually opt for a value of 18, imitating the relationship between
    70
       * Ether and Wei. This is the default value returned by this function, unless
    71
       * it's overridden.
    72
       *
    73
       * NOTE: This information is only used for _display_ purposes: it in
    74
       * no way affects any of the arithmetic of the contract, including
    75
       * {IERC20-balanceOf} and {IERC20-transfer}.
    76
       */
    77
      function decimals() public view virtual returns (uint8) {
    78
        return 18;
    79
      }
    80
    81
      /// @inheritdoc IERC20
    82
      function totalSupply() public view virtual returns (uint256) {
    83
        return _totalSupply;
    84
      }
    85
    86
      /// @inheritdoc IERC20
    87
      function balanceOf(address account) public view virtual returns (uint256) {
    88
        return _balances[account];
    89
      }
    90
    91
      /**
    92
       * @dev See {IERC20-transfer}.
    93
       *
    94
       * Requirements:
    95
       *
    96
       * - `to` cannot be the zero address.
    97
       * - the caller must have a balance of at least `value`.
    98
       */
    99
      function transfer(address to, uint256 value) public virtual returns (bool) {
    100
        address owner = _msgSender();
    101
        _transfer(owner, to, value);
    102
        return true;
    103
      }
    104
    105
      /// @inheritdoc IERC20
    106
      function allowance(address owner, address spender) public view virtual returns (uint256) {
    107
        return _allowances[owner][spender];
    108
      }
    109
    110
      /**
    111
       * @dev See {IERC20-approve}.
    112
       *
    113
       * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
    114
       * `transferFrom`. This is semantically equivalent to an infinite approval.
    115
       *
    116
       * Requirements:
    117
       *
    118
       * - `spender` cannot be the zero address.
    119
       */
    120
      function approve(address spender, uint256 value) public virtual returns (bool) {
    121
        address owner = _msgSender();
    122
        _approve(owner, spender, value);
    123
        return true;
    124
      }
    125
    126
      /**
    127
       * @dev See {IERC20-transferFrom}.
    128
       *
    129
       * Skips emitting an {Approval} event indicating an allowance update. This is not
    130
       * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].
    131
       *
    132
       * NOTE: Does not update the allowance if the current allowance
    133
       * is the maximum `uint256`.
    134
       *
    135
       * Requirements:
    136
       *
    137
       * - `from` and `to` cannot be the zero address.
    138
       * - `from` must have a balance of at least `value`.
    139
       * - the caller must have allowance for ``from``'s tokens of at least
    140
       * `value`.
    141
       */
    142
      function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
    143
        address spender = _msgSender();
    144
        _spendAllowance(from, spender, value);
    145
        _transfer(from, to, value);
    146
        return true;
    147
      }
    148
    149
      /**
    150
       * @dev Moves a `value` amount of tokens from `from` to `to`.
    151
       *
    152
       * This internal function is equivalent to {transfer}, and can be used to
    153
       * e.g. implement automatic token fees, slashing mechanisms, etc.
    154
       *
    155
       * Emits a {Transfer} event.
    156
       *
    157
       * NOTE: This function is not virtual, {_update} should be overridden instead.
    158
       */
    159
      function _transfer(address from, address to, uint256 value) internal {
    160
        if (from == address(0)) {
    161
          revert ERC20InvalidSender(address(0));
    162
        }
    163
        if (to == address(0)) {
    164
          revert ERC20InvalidReceiver(address(0));
    165
        }
    166
        _update(from, to, value);
    167
      }
    168
    169
      /**
    170
       * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
    171
       * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
    172
       * this function.
    173
       *
    174
       * Emits a {Transfer} event.
    175
       */
    176
      function _update(address from, address to, uint256 value) internal virtual {
    177
        if (from == address(0)) {
    178
          // Overflow check required: The rest of the code assumes that totalSupply never overflows
    179
          _totalSupply += value;
    180
        } else {
    181
          uint256 fromBalance = _balances[from];
    182
          if (fromBalance < value) {
    183
            revert ERC20InsufficientBalance(from, fromBalance, value);
    184
          }
    185
          unchecked {
    186
            // Overflow not possible: value <= fromBalance <= totalSupply.
    187
            _balances[from] = fromBalance - value;
    188
          }
    189
        }
    190
    191
        if (to == address(0)) {
    192
          unchecked {
    193
            // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
    194
            _totalSupply -= value;
    195
          }
    196
        } else {
    197
          unchecked {
    198
            // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
    199
            _balances[to] += value;
    200
          }
    201
        }
    202
    203
        emit Transfer(from, to, value);
    204
      }
    205
    206
      /**
    207
       * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
    208
       * Relies on the `_update` mechanism
    209
       *
    210
       * Emits a {Transfer} event with `from` set to the zero address.
    211
       *
    212
       * NOTE: This function is not virtual, {_update} should be overridden instead.
    213
       */
    214
      function _mint(address account, uint256 value) internal {
    215
        if (account == address(0)) {
    216
          revert ERC20InvalidReceiver(address(0));
    217
        }
    218
        _update(address(0), account, value);
    219
      }
    220
    221
      /**
    222
       * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
    223
       * Relies on the `_update` mechanism.
    224
       *
    225
       * Emits a {Transfer} event with `to` set to the zero address.
    226
       *
    227
       * NOTE: This function is not virtual, {_update} should be overridden instead
    228
       */
    229
      function _burn(address account, uint256 value) internal {
    230
        if (account == address(0)) {
    231
          revert ERC20InvalidSender(address(0));
    232
        }
    233
        _update(account, address(0), value);
    234
      }
    235
    236
      /**
    237
       * @dev Sets `value` as the allowance of `spender` over the `owner`'s tokens.
    238
       *
    239
       * This internal function is equivalent to `approve`, and can be used to
    240
       * e.g. set automatic allowances for certain subsystems, etc.
    241
       *
    242
       * Emits an {Approval} event.
    243
       *
    244
       * Requirements:
    245
       *
    246
       * - `owner` cannot be the zero address.
    247
       * - `spender` cannot be the zero address.
    248
       *
    249
       * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
    250
       */
    251
      function _approve(address owner, address spender, uint256 value) internal {
    252
        _approve(owner, spender, value, true);
    253
      }
    254
    255
      /**
    256
       * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
    257
       *
    258
       * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
    259
       * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any
    260
       * `Approval` event during `transferFrom` operations.
    261
       *
    262
       * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to
    263
       * true using the following override:
    264
       *
    265
       * ```solidity
    266
       * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
    267
       *     super._approve(owner, spender, value, true);
    268
       * }
    269
       * ```
    270
       *
    271
       * Requirements are the same as {_approve}.
    272
       */
    273
      function _approve(
    274
        address owner,
    275
        address spender,
    276
        uint256 value,
    277
        bool emitEvent
    278
      ) internal virtual {
    279
        if (owner == address(0)) {
    280
          revert ERC20InvalidApprover(address(0));
    281
        }
    282
        if (spender == address(0)) {
    283
          revert ERC20InvalidSpender(address(0));
    284
        }
    285
        _allowances[owner][spender] = value;
    286
        if (emitEvent) {
    287
          emit Approval(owner, spender, value);
    288
        }
    289
      }
    290
    291
      /**
    292
       * @dev Updates `owner`'s allowance for `spender` based on spent `value`.
    293
       *
    294
       * Does not update the allowance value in case of infinite allowance.
    295
       * Revert if not enough allowance is available.
    296
       *
    297
       * Does not emit an {Approval} event.
    298
       */
    299
      function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
    300
        uint256 currentAllowance = allowance(owner, spender);
    301
        if (currentAllowance < type(uint256).max) {
    302
          if (currentAllowance < value) {
    303
            revert ERC20InsufficientAllowance(spender, currentAllowance, value);
    304
          }
    305
          unchecked {
    306
            _approve(owner, spender, currentAllowance - value, false);
    307
          }
    308
        }
    309
      }
    310
    }
    311
    0.0% src/dependencies/openzeppelin/EnumerableSet.sol
    Lines covered: 0 / 7 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.4.0) (utils/structs/EnumerableSet.sol)
    3
    // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.
    4
    5
    pragma solidity ^0.8.20;
    6
    7
    import {Arrays} from './Arrays.sol';
    8
    import {Math} from './Math.sol';
    9
    10
    /**
    11
     * @dev Library for managing
    12
     * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
    13
     * types.
    14
     *
    15
     * Sets have the following properties:
    16
     *
    17
     * - Elements are added, removed, and checked for existence in constant time
    18
     * (O(1)).
    19
     * - Elements are enumerated in O(n). No guarantees are made on the ordering.
    20
     * - Set can be cleared (all elements removed) in O(n).
    21
     *
    22
     * ```solidity
    23
     * contract Example {
    24
     *     // Add the library methods
    25
     *     using EnumerableSet for EnumerableSet.AddressSet;
    26
     *
    27
     *     // Declare a set state variable
    28
     *     EnumerableSet.AddressSet private mySet;
    29
     * }
    30
     * ```
    31
     *
    32
     * The following types are supported:
    33
     *
    34
     * - `bytes32` (`Bytes32Set`) since v3.3.0
    35
     * - `address` (`AddressSet`) since v3.3.0
    36
     * - `uint256` (`UintSet`) since v3.3.0
    37
     * - `string` (`StringSet`) since v5.4.0
    38
     * - `bytes` (`BytesSet`) since v5.4.0
    39
     *
    40
     * [WARNING]
    41
     * ====
    42
     * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
    43
     * unusable.
    44
     * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
    45
     *
    46
     * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
    47
     * array of EnumerableSet.
    48
     * ====
    49
     */
    50
    library EnumerableSet {
    51
      // To implement this library for multiple types with as little code
    52
      // repetition as possible, we write it in terms of a generic Set type with
    53
      // bytes32 values.
    54
      // The Set implementation uses private functions, and user-facing
    55
      // implementations (such as AddressSet) are just wrappers around the
    56
      // underlying Set.
    57
      // This means that we can only create new EnumerableSets for types that fit
    58
      // in bytes32.
    59
    60
      struct Set {
    61
        // Storage of set values
    62
        bytes32[] _values;
    63
        // Position is the index of the value in the `values` array plus 1.
    64
        // Position 0 is used to mean a value is not in the set.
    65
        mapping(bytes32 value => uint256) _positions;
    66
      }
    67
    68
      /**
    69
       * @dev Add a value to a set. O(1).
    70
       *
    71
       * Returns true if the value was added to the set, that is if it was not
    72
       * already present.
    73
       */
    74
      function _add(Set storage set, bytes32 value) private returns (bool) {
    75
        if (!_contains(set, value)) {
    76
          set._values.push(value);
    77
          // The value is stored at length-1, but we add 1 to all indexes
    78
          // and use 0 as a sentinel value
    79
          set._positions[value] = set._values.length;
    80
          return true;
    81
        } else {
    82
          return false;
    83
        }
    84
      }
    85
    86
      /**
    87
       * @dev Removes a value from a set. O(1).
    88
       *
    89
       * Returns true if the value was removed from the set, that is if it was
    90
       * present.
    91
       */
    92
      function _remove(Set storage set, bytes32 value) private returns (bool) {
    93
        // We cache the value's position to prevent multiple reads from the same storage slot
    94
        uint256 position = set._positions[value];
    95
    96
        if (position != 0) {
    97
          // Equivalent to contains(set, value)
    98
          // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
    99
          // the array, and then remove the last element (sometimes called as 'swap and pop').
    100
          // This modifies the order of the array, as noted in {at}.
    101
    102
          uint256 valueIndex = position - 1;
    103
          uint256 lastIndex = set._values.length - 1;
    104
    105
          if (valueIndex != lastIndex) {
    106
            bytes32 lastValue = set._values[lastIndex];
    107
    108
            // Move the lastValue to the index where the value to delete is
    109
            set._values[valueIndex] = lastValue;
    110
            // Update the tracked position of the lastValue (that was just moved)
    111
            set._positions[lastValue] = position;
    112
          }
    113
    114
          // Delete the slot where the moved value was stored
    115
          set._values.pop();
    116
    117
          // Delete the tracked position for the deleted slot
    118
          delete set._positions[value];
    119
    120
          return true;
    121
        } else {
    122
          return false;
    123
        }
    124
      }
    125
    126
      /**
    127
       * @dev Removes all the values from a set. O(n).
    128
       *
    129
       * WARNING: This function has an unbounded cost that scales with set size. Developers should keep in mind that
    130
       * using it may render the function uncallable if the set grows to the point where clearing it consumes too much
    131
       * gas to fit in a block.
    132
       */
    133
      function _clear(Set storage set) private {
    134
        uint256 len = _length(set);
    135
        for (uint256 i = 0; i < len; ++i) {
    136
          delete set._positions[set._values[i]];
    137
        }
    138
        Arrays.unsafeSetLength(set._values, 0);
    139
      }
    140
    141
      /**
    142
       * @dev Returns true if the value is in the set. O(1).
    143
       */
    144
      function _contains(Set storage set, bytes32 value) private view returns (bool) {
    145
        return set._positions[value] != 0;
    146
      }
    147
    148
      /**
    149
       * @dev Returns the number of values on the set. O(1).
    150
       */
    151
      function _length(Set storage set) private view returns (uint256) {
    152
        return set._values.length;
    153
      }
    154
    155
      /**
    156
       * @dev Returns the value stored at position `index` in the set. O(1).
    157
       *
    158
       * Note that there are no guarantees on the ordering of values inside the
    159
       * array, and it may change when more values are added or removed.
    160
       *
    161
       * Requirements:
    162
       *
    163
       * - `index` must be strictly less than {length}.
    164
       */
    165
      function _at(Set storage set, uint256 index) private view returns (bytes32) {
    166
        return set._values[index];
    167
      }
    168
    169
      /**
    170
       * @dev Return the entire set in an array
    171
       *
    172
       * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
    173
       * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
    174
       * this function has an unbounded cost, and using it as part of a state-changing function may render the function
    175
       * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
    176
       */
    177
      function _values(Set storage set) private view returns (bytes32[] memory) {
    178
        return set._values;
    179
      }
    180
    181
      /**
    182
       * @dev Return a slice of the set in an array
    183
       *
    184
       * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
    185
       * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
    186
       * this function has an unbounded cost, and using it as part of a state-changing function may render the function
    187
       * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
    188
       */
    189
      function _values(
    190
        Set storage set,
    191
        uint256 start,
    192
        uint256 end
    193
      ) private view returns (bytes32[] memory) {
    194
        unchecked {
    195
          end = Math.min(end, _length(set));
    196
          start = Math.min(start, end);
    197
    198
          uint256 len = end - start;
    199
          bytes32[] memory result = new bytes32[](len);
    200
          for (uint256 i = 0; i < len; ++i) {
    201
            result[i] = Arrays.unsafeAccess(set._values, start + i).value;
    202
          }
    203
          return result;
    204
        }
    205
      }
    206
    207
      // Bytes32Set
    208
    209
      struct Bytes32Set {
    210
        Set _inner;
    211
      }
    212
    213
      /**
    214
       * @dev Add a value to a set. O(1).
    215
       *
    216
       * Returns true if the value was added to the set, that is if it was not
    217
       * already present.
    218
       */
    219
      function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
    220
        return _add(set._inner, value);
    221
      }
    222
    223
      /**
    224
       * @dev Removes a value from a set. O(1).
    225
       *
    226
       * Returns true if the value was removed from the set, that is if it was
    227
       * present.
    228
       */
    229
      function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
    230
        return _remove(set._inner, value);
    231
      }
    232
    233
      /**
    234
       * @dev Removes all the values from a set. O(n).
    235
       *
    236
       * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
    237
       * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
    238
       */
    239
      function clear(Bytes32Set storage set) internal {
    240
        _clear(set._inner);
    241
      }
    242
    243
      /**
    244
       * @dev Returns true if the value is in the set. O(1).
    245
       */
    246
      function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
    247
        return _contains(set._inner, value);
    248
      }
    249
    250
      /**
    251
       * @dev Returns the number of values in the set. O(1).
    252
       */
    253
      function length(Bytes32Set storage set) internal view returns (uint256) {
    254
        return _length(set._inner);
    255
      }
    256
    257
      /**
    258
       * @dev Returns the value stored at position `index` in the set. O(1).
    259
       *
    260
       * Note that there are no guarantees on the ordering of values inside the
    261
       * array, and it may change when more values are added or removed.
    262
       *
    263
       * Requirements:
    264
       *
    265
       * - `index` must be strictly less than {length}.
    266
       */
    267
      function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
    268
        return _at(set._inner, index);
    269
      }
    270
    271
      /**
    272
       * @dev Return the entire set in an array
    273
       *
    274
       * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
    275
       * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
    276
       * this function has an unbounded cost, and using it as part of a state-changing function may render the function
    277
       * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
    278
       */
    279
      function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
    280
        bytes32[] memory store = _values(set._inner);
    281
        bytes32[] memory result;
    282
    283
        assembly ('memory-safe') {
    284
          result := store
    285
        }
    286
    287
        return result;
    288
      }
    289
    290
      /**
    291
       * @dev Return a slice of the set in an array
    292
       *
    293
       * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
    294
       * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
    295
       * this function has an unbounded cost, and using it as part of a state-changing function may render the function
    296
       * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
    297
       */
    298
      function values(
    299
        Bytes32Set storage set,
    300
        uint256 start,
    301
        uint256 end
    302
      ) internal view returns (bytes32[] memory) {
    303
        bytes32[] memory store = _values(set._inner, start, end);
    304
        bytes32[] memory result;
    305
    306
        assembly ('memory-safe') {
    307
          result := store
    308
        }
    309
    310
        return result;
    311
      }
    312
    313
      // AddressSet
    314
    315
      struct AddressSet {
    316
        Set _inner;
    317
      }
    318
    319
      /**
    320
       * @dev Add a value to a set. O(1).
    321
       *
    322
       * Returns true if the value was added to the set, that is if it was not
    323
       * already present.
    324
       */
    325
      function add(AddressSet storage set, address value) internal returns (bool) {
    326
        return _add(set._inner, bytes32(uint256(uint160(value))));
    327
      }
    328
    329
      /**
    330
       * @dev Removes a value from a set. O(1).
    331
       *
    332
       * Returns true if the value was removed from the set, that is if it was
    333
       * present.
    334
       */
    335
      function remove(AddressSet storage set, address value) internal returns (bool) {
    336
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    337
      }
    338
    339
      /**
    340
       * @dev Removes all the values from a set. O(n).
    341
       *
    342
       * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
    343
       * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
    344
       */
    345
      function clear(AddressSet storage set) internal {
    346
        _clear(set._inner);
    347
      }
    348
    349
      /**
    350
       * @dev Returns true if the value is in the set. O(1).
    351
       */
    352
      function contains(AddressSet storage set, address value) internal view returns (bool) {
    353
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    354
      }
    355
    356
      /**
    357
       * @dev Returns the number of values in the set. O(1).
    358
       */
    359
      function length(AddressSet storage set) internal view returns (uint256) {
    360
        return _length(set._inner);
    361
      }
    362
    363
      /**
    364
       * @dev Returns the value stored at position `index` in the set. O(1).
    365
       *
    366
       * Note that there are no guarantees on the ordering of values inside the
    367
       * array, and it may change when more values are added or removed.
    368
       *
    369
       * Requirements:
    370
       *
    371
       * - `index` must be strictly less than {length}.
    372
       */
    373
      function at(AddressSet storage set, uint256 index) internal view returns (address) {
    374
        return address(uint160(uint256(_at(set._inner, index))));
    375
      }
    376
    377
      /**
    378
       * @dev Return the entire set in an array
    379
       *
    380
       * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
    381
       * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
    382
       * this function has an unbounded cost, and using it as part of a state-changing function may render the function
    383
       * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
    384
       */
    385
      function values(AddressSet storage set) internal view returns (address[] memory) {
    386
        bytes32[] memory store = _values(set._inner);
    387
        address[] memory result;
    388
    389
        assembly ('memory-safe') {
    390
          result := store
    391
        }
    392
    393
        return result;
    394
      }
    395
    396
      /**
    397
       * @dev Return a slice of the set in an array
    398
       *
    399
       * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
    400
       * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
    401
       * this function has an unbounded cost, and using it as part of a state-changing function may render the function
    402
       * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
    403
       */
    404
      function values(
    405
        AddressSet storage set,
    406
        uint256 start,
    407
        uint256 end
    408
      ) internal view returns (address[] memory) {
    409
        bytes32[] memory store = _values(set._inner, start, end);
    410
        address[] memory result;
    411
    412
        assembly ('memory-safe') {
    413
          result := store
    414
        }
    415
    416
        return result;
    417
      }
    418
    419
      // UintSet
    420
    421
      struct UintSet {
    422
        Set _inner;
    423
      }
    424
    425
      /**
    426
       * @dev Add a value to a set. O(1).
    427
       *
    428
       * Returns true if the value was added to the set, that is if it was not
    429
       * already present.
    430
       */
    431
      function add(UintSet storage set, uint256 value) internal returns (bool) {
    432
        return _add(set._inner, bytes32(value));
    433
      }
    434
    435
      /**
    436
       * @dev Removes a value from a set. O(1).
    437
       *
    438
       * Returns true if the value was removed from the set, that is if it was
    439
       * present.
    440
       */
    441
      function remove(UintSet storage set, uint256 value) internal returns (bool) {
    442
        return _remove(set._inner, bytes32(value));
    443
      }
    444
    445
      /**
    446
       * @dev Removes all the values from a set. O(n).
    447
       *
    448
       * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
    449
       * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
    450
       */
    451
      function clear(UintSet storage set) internal {
    452
        _clear(set._inner);
    453
      }
    454
    455
      /**
    456
       * @dev Returns true if the value is in the set. O(1).
    457
       */
    458
      function contains(UintSet storage set, uint256 value) internal view returns (bool) {
    459
        return _contains(set._inner, bytes32(value));
    460
      }
    461
    462
      /**
    463
       * @dev Returns the number of values in the set. O(1).
    464
       */
    465
      function length(UintSet storage set) internal view returns (uint256) {
    466
        return _length(set._inner);
    467
      }
    468
    469
      /**
    470
       * @dev Returns the value stored at position `index` in the set. O(1).
    471
       *
    472
       * Note that there are no guarantees on the ordering of values inside the
    473
       * array, and it may change when more values are added or removed.
    474
       *
    475
       * Requirements:
    476
       *
    477
       * - `index` must be strictly less than {length}.
    478
       */
    479
      function at(UintSet storage set, uint256 index) internal view returns (uint256) {
    480
        return uint256(_at(set._inner, index));
    481
      }
    482
    483
      /**
    484
       * @dev Return the entire set in an array
    485
       *
    486
       * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
    487
       * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
    488
       * this function has an unbounded cost, and using it as part of a state-changing function may render the function
    489
       * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
    490
       */
    491
      function values(UintSet storage set) internal view returns (uint256[] memory) {
    492
        bytes32[] memory store = _values(set._inner);
    493
        uint256[] memory result;
    494
    495
        assembly ('memory-safe') {
    496
          result := store
    497
        }
    498
    499
        return result;
    500
      }
    501
    502
      /**
    503
       * @dev Return a slice of the set in an array
    504
       *
    505
       * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
    506
       * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
    507
       * this function has an unbounded cost, and using it as part of a state-changing function may render the function
    508
       * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
    509
       */
    510
      function values(
    511
        UintSet storage set,
    512
        uint256 start,
    513
        uint256 end
    514
      ) internal view returns (uint256[] memory) {
    515
        bytes32[] memory store = _values(set._inner, start, end);
    516
        uint256[] memory result;
    517
    518
        assembly ('memory-safe') {
    519
          result := store
    520
        }
    521
    522
        return result;
    523
      }
    524
    525
      struct StringSet {
    526
        // Storage of set values
    527
        string[] _values;
    528
        // Position is the index of the value in the `values` array plus 1.
    529
        // Position 0 is used to mean a value is not in the set.
    530
        mapping(string value => uint256) _positions;
    531
      }
    532
    533
      /**
    534
       * @dev Add a value to a set. O(1).
    535
       *
    536
       * Returns true if the value was added to the set, that is if it was not
    537
       * already present.
    538
       */
    539
      function add(StringSet storage set, string memory value) internal returns (bool) {
    540
        if (!contains(set, value)) {
    541
          set._values.push(value);
    542
          // The value is stored at length-1, but we add 1 to all indexes
    543
          // and use 0 as a sentinel value
    544
          set._positions[value] = set._values.length;
    545
          return true;
    546
        } else {
    547
          return false;
    548
        }
    549
      }
    550
    551
      /**
    552
       * @dev Removes a value from a set. O(1).
    553
       *
    554
       * Returns true if the value was removed from the set, that is if it was
    555
       * present.
    556
       */
    557
      function remove(StringSet storage set, string memory value) internal returns (bool) {
    558
        // We cache the value's position to prevent multiple reads from the same storage slot
    559
        uint256 position = set._positions[value];
    560
    561
        if (position != 0) {
    562
          // Equivalent to contains(set, value)
    563
          // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
    564
          // the array, and then remove the last element (sometimes called as 'swap and pop').
    565
          // This modifies the order of the array, as noted in {at}.
    566
    567
          uint256 valueIndex = position - 1;
    568
          uint256 lastIndex = set._values.length - 1;
    569
    570
          if (valueIndex != lastIndex) {
    571
            string memory lastValue = set._values[lastIndex];
    572
    573
            // Move the lastValue to the index where the value to delete is
    574
            set._values[valueIndex] = lastValue;
    575
            // Update the tracked position of the lastValue (that was just moved)
    576
            set._positions[lastValue] = position;
    577
          }
    578
    579
          // Delete the slot where the moved value was stored
    580
          set._values.pop();
    581
    582
          // Delete the tracked position for the deleted slot
    583
          delete set._positions[value];
    584
    585
          return true;
    586
        } else {
    587
          return false;
    588
        }
    589
      }
    590
    591
      /**
    592
       * @dev Removes all the values from a set. O(n).
    593
       *
    594
       * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
    595
       * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
    596
       */
    597
      function clear(StringSet storage set) internal {
    598
        uint256 len = length(set);
    599
        for (uint256 i = 0; i < len; ++i) {
    600
          delete set._positions[set._values[i]];
    601
        }
    602
        Arrays.unsafeSetLength(set._values, 0);
    603
      }
    604
    605
      /**
    606
       * @dev Returns true if the value is in the set. O(1).
    607
       */
    608
      function contains(StringSet storage set, string memory value) internal view returns (bool) {
    609
        return set._positions[value] != 0;
    610
      }
    611
    612
      /**
    613
       * @dev Returns the number of values on the set. O(1).
    614
       */
    615
      function length(StringSet storage set) internal view returns (uint256) {
    616
        return set._values.length;
    617
      }
    618
    619
      /**
    620
       * @dev Returns the value stored at position `index` in the set. O(1).
    621
       *
    622
       * Note that there are no guarantees on the ordering of values inside the
    623
       * array, and it may change when more values are added or removed.
    624
       *
    625
       * Requirements:
    626
       *
    627
       * - `index` must be strictly less than {length}.
    628
       */
    629
      function at(StringSet storage set, uint256 index) internal view returns (string memory) {
    630
        return set._values[index];
    631
      }
    632
    633
      /**
    634
       * @dev Return the entire set in an array
    635
       *
    636
       * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
    637
       * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
    638
       * this function has an unbounded cost, and using it as part of a state-changing function may render the function
    639
       * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
    640
       */
    641
      function values(StringSet storage set) internal view returns (string[] memory) {
    642
        return set._values;
    643
      }
    644
    645
      /**
    646
       * @dev Return a slice of the set in an array
    647
       *
    648
       * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
    649
       * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
    650
       * this function has an unbounded cost, and using it as part of a state-changing function may render the function
    651
       * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
    652
       */
    653
      function values(
    654
        StringSet storage set,
    655
        uint256 start,
    656
        uint256 end
    657
      ) internal view returns (string[] memory) {
    658
        unchecked {
    659
          end = Math.min(end, length(set));
    660
          start = Math.min(start, end);
    661
    662
          uint256 len = end - start;
    663
          string[] memory result = new string[](len);
    664
          for (uint256 i = 0; i < len; ++i) {
    665
            result[i] = Arrays.unsafeAccess(set._values, start + i).value;
    666
          }
    667
          return result;
    668
        }
    669
      }
    670
    671
      struct BytesSet {
    672
        // Storage of set values
    673
        bytes[] _values;
    674
        // Position is the index of the value in the `values` array plus 1.
    675
        // Position 0 is used to mean a value is not in the set.
    676
        mapping(bytes value => uint256) _positions;
    677
      }
    678
    679
      /**
    680
       * @dev Add a value to a set. O(1).
    681
       *
    682
       * Returns true if the value was added to the set, that is if it was not
    683
       * already present.
    684
       */
    685
      function add(BytesSet storage set, bytes memory value) internal returns (bool) {
    686
        if (!contains(set, value)) {
    687
          set._values.push(value);
    688
          // The value is stored at length-1, but we add 1 to all indexes
    689
          // and use 0 as a sentinel value
    690
          set._positions[value] = set._values.length;
    691
          return true;
    692
        } else {
    693
          return false;
    694
        }
    695
      }
    696
    697
      /**
    698
       * @dev Removes a value from a set. O(1).
    699
       *
    700
       * Returns true if the value was removed from the set, that is if it was
    701
       * present.
    702
       */
    703
      function remove(BytesSet storage set, bytes memory value) internal returns (bool) {
    704
        // We cache the value's position to prevent multiple reads from the same storage slot
    705
        uint256 position = set._positions[value];
    706
    707
        if (position != 0) {
    708
          // Equivalent to contains(set, value)
    709
          // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
    710
          // the array, and then remove the last element (sometimes called as 'swap and pop').
    711
          // This modifies the order of the array, as noted in {at}.
    712
    713
          uint256 valueIndex = position - 1;
    714
          uint256 lastIndex = set._values.length - 1;
    715
    716
          if (valueIndex != lastIndex) {
    717
            bytes memory lastValue = set._values[lastIndex];
    718
    719
            // Move the lastValue to the index where the value to delete is
    720
            set._values[valueIndex] = lastValue;
    721
            // Update the tracked position of the lastValue (that was just moved)
    722
            set._positions[lastValue] = position;
    723
          }
    724
    725
          // Delete the slot where the moved value was stored
    726
          set._values.pop();
    727
    728
          // Delete the tracked position for the deleted slot
    729
          delete set._positions[value];
    730
    731
          return true;
    732
        } else {
    733
          return false;
    734
        }
    735
      }
    736
    737
      /**
    738
       * @dev Removes all the values from a set. O(n).
    739
       *
    740
       * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
    741
       * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
    742
       */
    743
      function clear(BytesSet storage set) internal {
    744
        uint256 len = length(set);
    745
        for (uint256 i = 0; i < len; ++i) {
    746
          delete set._positions[set._values[i]];
    747
        }
    748
        Arrays.unsafeSetLength(set._values, 0);
    749
      }
    750
    751
      /**
    752
       * @dev Returns true if the value is in the set. O(1).
    753
       */
    754
      function contains(BytesSet storage set, bytes memory value) internal view returns (bool) {
    755
        return set._positions[value] != 0;
    756
      }
    757
    758
      /**
    759
       * @dev Returns the number of values on the set. O(1).
    760
       */
    761
      function length(BytesSet storage set) internal view returns (uint256) {
    762
        return set._values.length;
    763
      }
    764
    765
      /**
    766
       * @dev Returns the value stored at position `index` in the set. O(1).
    767
       *
    768
       * Note that there are no guarantees on the ordering of values inside the
    769
       * array, and it may change when more values are added or removed.
    770
       *
    771
       * Requirements:
    772
       *
    773
       * - `index` must be strictly less than {length}.
    774
       */
    775
      function at(BytesSet storage set, uint256 index) internal view returns (bytes memory) {
    776
        return set._values[index];
    777
      }
    778
    779
      /**
    780
       * @dev Return the entire set in an array
    781
       *
    782
       * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
    783
       * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
    784
       * this function has an unbounded cost, and using it as part of a state-changing function may render the function
    785
       * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
    786
       */
    787
      function values(BytesSet storage set) internal view returns (bytes[] memory) {
    788
        return set._values;
    789
      }
    790
    791
      /**
    792
       * @dev Return a slice of the set in an array
    793
       *
    794
       * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
    795
       * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
    796
       * this function has an unbounded cost, and using it as part of a state-changing function may render the function
    797
       * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
    798
       */
    799
      function values(
    800
        BytesSet storage set,
    801
        uint256 start,
    802
        uint256 end
    803
      ) internal view returns (bytes[] memory) {
    804
        unchecked {
    805
          end = Math.min(end, length(set));
    806
          start = Math.min(start, end);
    807
    808
          uint256 len = end - start;
    809
          bytes[] memory result = new bytes[](len);
    810
          for (uint256 i = 0; i < len; ++i) {
    811
            result[i] = Arrays.unsafeAccess(set._values, start + i).value;
    812
          }
    813
          return result;
    814
        }
    815
      }
    816
    }
    817
    33.0% src/dependencies/openzeppelin/Errors.sol
    Lines covered: 1 / 3 (33.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol)
    3
    4
    pragma solidity ^0.8.20;
    5
    6
    /**
    7
     * @dev Collection of common custom errors used in multiple contracts
    8
     *
    9
     * IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library.
    10
     * It is recommended to avoid relying on the error API for critical functionality.
    11
     *
    12
     * _Available since v5.1._
    13
     */
    14
    library Errors {
    15
      /**
    16
       * @dev The ETH balance of the account is not enough to perform the operation.
    17
       */
    18
      error InsufficientBalance(uint256 balance, uint256 needed);
    19
    20
      /**
    21
       * @dev A call to an address target failed. The target may have reverted.
    22
       */
    23
      error FailedCall();
    24
    25
      /**
    26
       * @dev The deployment failed.
    27
       */
    28
      error FailedDeployment();
    29
    30
      /**
    31
       * @dev A necessary precompile is missing.
    32
       */
    33
      error MissingPrecompile(address);
    34
    }
    35
    100.0% src/dependencies/openzeppelin/IAccessManaged.sol
    Lines covered: 1 / 1 (100.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.4.0) (access/manager/IAccessManaged.sol)
    3
    4
    pragma solidity >=0.8.4;
    5
    6
    interface IAccessManaged {
    7
      /**
    8
       * @dev Authority that manages this contract was updated.
    9
       */
    10
      event AuthorityUpdated(address authority);
    11
    12
      error AccessManagedUnauthorized(address caller);
    13
      error AccessManagedRequiredDelay(address caller, uint32 delay);
    14
      error AccessManagedInvalidAuthority(address authority);
    15
    16
      /**
    17
       * @dev Returns the current authority.
    18
       */
    19
      function authority() external view returns (address);
    20
    21
      /**
    22
       * @dev Transfers control to a new authority. The caller must be the current authority.
    23
       */
    24
      function setAuthority(address) external;
    25
    26
      /**
    27
       * @dev Returns true only in the context of a delayed restricted call, at the moment that the scheduled operation is
    28
       * being consumed. Prevents denial of service for delayed restricted calls in the case that the contract performs
    29
       * attacker controlled calls.
    30
       */
    31
      function isConsumingScheduledOp() external view returns (bytes4);
    32
    }
    33
    66.0% src/dependencies/openzeppelin/IAccessManager.sol
    Lines covered: 36 / 54 (66.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.4.0) (access/manager/IAccessManager.sol)
    3
    4
    pragma solidity >=0.8.4;
    5
    6
    interface IAccessManager {
    7
      /**
    8
       * @dev A delayed operation was scheduled.
    9
       */
    10
      event OperationScheduled(
    11
        bytes32 indexed operationId,
    12
        uint32 indexed nonce,
    13
        uint48 schedule,
    14
        address caller,
    15
        address target,
    16
        bytes data
    17
      );
    18
    19
      /**
    20
       * @dev A scheduled operation was executed.
    21
       */
    22
      event OperationExecuted(bytes32 indexed operationId, uint32 indexed nonce);
    23
    24
      /**
    25
       * @dev A scheduled operation was canceled.
    26
       */
    27
      event OperationCanceled(bytes32 indexed operationId, uint32 indexed nonce);
    28
    29
      /**
    30
       * @dev Informational labelling for a roleId.
    31
       */
    32
      event RoleLabel(uint64 indexed roleId, string label);
    33
    34
      /**
    35
       * @dev Emitted when `account` is granted `roleId`.
    36
       *
    37
       * NOTE: The meaning of the `since` argument depends on the `newMember` argument.
    38
       * If the role is granted to a new member, the `since` argument indicates when the account becomes a member of the role,
    39
       * otherwise it indicates the execution delay for this account and roleId is updated.
    40
       */
    41
      event RoleGranted(
    42
        uint64 indexed roleId,
    43
        address indexed account,
    44
        uint32 delay,
    45
        uint48 since,
    46
        bool newMember
    47
      );
    48
    49
      /**
    50
       * @dev Emitted when `account` membership or `roleId` is revoked. Unlike granting, revoking is instantaneous.
    51
       */
    52
      event RoleRevoked(uint64 indexed roleId, address indexed account);
    53
    54
      /**
    55
       * @dev Role acting as admin over a given `roleId` is updated.
    56
       */
    57
      event RoleAdminChanged(uint64 indexed roleId, uint64 indexed admin);
    58
    59
      /**
    60
       * @dev Role acting as guardian over a given `roleId` is updated.
    61
       */
    62
      event RoleGuardianChanged(uint64 indexed roleId, uint64 indexed guardian);
    63
    64
      /**
    65
       * @dev Grant delay for a given `roleId` will be updated to `delay` when `since` is reached.
    66
       */
    67
      event RoleGrantDelayChanged(uint64 indexed roleId, uint32 delay, uint48 since);
    68
    69
      /**
    70
       * @dev Target mode is updated (true = closed, false = open).
    71
       */
    72
      event TargetClosed(address indexed target, bool closed);
    73
    74
      /**
    75
       * @dev Role required to invoke `selector` on `target` is updated to `roleId`.
    76
       */
    77
      event TargetFunctionRoleUpdated(address indexed target, bytes4 selector, uint64 indexed roleId);
    78
    79
      /**
    80
       * @dev Admin delay for a given `target` will be updated to `delay` when `since` is reached.
    81
       */
    82
      event TargetAdminDelayUpdated(address indexed target, uint32 delay, uint48 since);
    83
    84
      error AccessManagerAlreadyScheduled(bytes32 operationId);
    85
      error AccessManagerNotScheduled(bytes32 operationId);
    86
      error AccessManagerNotReady(bytes32 operationId);
    87
      error AccessManagerExpired(bytes32 operationId);
    88
      error AccessManagerLockedRole(uint64 roleId);
    89
      error AccessManagerBadConfirmation();
    90
      error AccessManagerUnauthorizedAccount(address msgsender, uint64 roleId);
    91
      error AccessManagerUnauthorizedCall(address caller, address target, bytes4 selector);
    92
      error AccessManagerUnauthorizedConsume(address target);
    93
      error AccessManagerUnauthorizedCancel(
    94
        address msgsender,
    95
        address caller,
    96
        address target,
    97
        bytes4 selector
    98
      );
    99
      error AccessManagerInvalidInitialAdmin(address initialAdmin);
    100
    101
      /**
    102
       * @dev Check if an address (`caller`) is authorised to call a given function on a given contract directly (with
    103
       * no restriction). Additionally, it returns the delay needed to perform the call indirectly through the {schedule}
    104
       * & {execute} workflow.
    105
       *
    106
       * This function is usually called by the targeted contract to control immediate execution of restricted functions.
    107
       * Therefore we only return true if the call can be performed without any delay. If the call is subject to a
    108
       * previously set delay (not zero), then the function should return false and the caller should schedule the operation
    109
       * for future execution.
    110
       *
    111
       * If `allowed` is true, the delay can be disregarded and the operation can be immediately executed, otherwise
    112
       * the operation can be executed if and only if delay is greater than 0.
    113
       *
    114
       * NOTE: The IAuthority interface does not include the `uint32` delay. This is an extension of that interface that
    115
       * is backward compatible. Some contracts may thus ignore the second return argument. In that case they will fail
    116
       * to identify the indirect workflow, and will consider calls that require a delay to be forbidden.
    117
       *
    118
       * NOTE: This function does not report the permissions of the admin functions in the manager itself. These are defined by the
    119
       * {AccessManager} documentation.
    120
       */
    121
      function canCall(
    122
        address caller,
    123
        address target,
    124
        bytes4 selector
    125
      ) external view returns (bool allowed, uint32 delay);
    126
    127
      /**
    128
       * @dev Expiration delay for scheduled proposals. Defaults to 1 week.
    129
       *
    130
       * IMPORTANT: Avoid overriding the expiration with 0. Otherwise every contract proposal will be expired immediately,
    131
       * disabling any scheduling usage.
    132
       */
    133
      function expiration() external view returns (uint32);
    134
    135
      /**
    136
       * @dev Minimum setback for all delay updates, with the exception of execution delays. It
    137
       * can be increased without setback (and reset via {revokeRole} in the case event of an
    138
       * accidental increase). Defaults to 5 days.
    139
       */
    140
      function minSetback() external view returns (uint32);
    141
    142
      /**
    143
       * @dev Get whether the contract is closed disabling any access. Otherwise role permissions are applied.
    144
       *
    145
       * NOTE: When the manager itself is closed, admin functions are still accessible to avoid locking the contract.
    146
       */
    147
      function isTargetClosed(address target) external view returns (bool);
    148
    149
      /**
    150
       * @dev Get the role required to call a function.
    151
       */
    152
      function getTargetFunctionRole(address target, bytes4 selector) external view returns (uint64);
    153
    154
      /**
    155
       * @dev Get the admin delay for a target contract. Changes to contract configuration are subject to this delay.
    156
       */
    157
      function getTargetAdminDelay(address target) external view returns (uint32);
    158
    159
      /**
    160
       * @dev Get the id of the role that acts as an admin for the given role.
    161
       *
    162
       * The admin permission is required to grant the role, revoke the role and update the execution delay to execute
    163
       * an operation that is restricted to this role.
    164
       */
    165
      function getRoleAdmin(uint64 roleId) external view returns (uint64);
    166
    167
      /**
    168
       * @dev Get the role that acts as a guardian for a given role.
    169
       *
    170
       * The guardian permission allows canceling operations that have been scheduled under the role.
    171
       */
    172
      function getRoleGuardian(uint64 roleId) external view returns (uint64);
    173
    174
      /**
    175
       * @dev Get the role current grant delay.
    176
       *
    177
       * Its value may change at any point without an event emitted following a call to {setGrantDelay}.
    178
       * Changes to this value, including effect timepoint are notified in advance by the {RoleGrantDelayChanged} event.
    179
       */
    180
      function getRoleGrantDelay(uint64 roleId) external view returns (uint32);
    181
    182
      /**
    183
       * @dev Get the access details for a given account for a given role. These details include the timepoint at which
    184
       * membership becomes active, and the delay applied to all operation by this user that requires this permission
    185
       * level.
    186
       *
    187
       * Returns:
    188
       * [0] Timestamp at which the account membership becomes valid. 0 means role is not granted.
    189
       * [1] Current execution delay for the account.
    190
       * [2] Pending execution delay for the account.
    191
       * [3] Timestamp at which the pending execution delay will become active. 0 means no delay update is scheduled.
    192
       */
    193
      function getAccess(
    194
        uint64 roleId,
    195
        address account
    196
      ) external view returns (uint48 since, uint32 currentDelay, uint32 pendingDelay, uint48 effect);
    197
    198
      /**
    199
       * @dev Check if a given account currently has the permission level corresponding to a given role. Note that this
    200
       * permission might be associated with an execution delay. {getAccess} can provide more details.
    201
       */
    202
      function hasRole(
    203
        uint64 roleId,
    204
        address account
    205
      ) external view returns (bool isMember, uint32 executionDelay);
    206
    207
      /**
    208
       * @dev Give a label to a role, for improved role discoverability by UIs.
    209
       *
    210
       * Requirements:
    211
       *
    212
       * - the caller must be a global admin
    213
       *
    214
       * Emits a {RoleLabel} event.
    215
       */
    216
      function labelRole(uint64 roleId, string calldata label) external;
    217
    218
      /**
    219
       * @dev Add `account` to `roleId`, or change its execution delay.
    220
       *
    221
       * This gives the account the authorization to call any function that is restricted to this role. An optional
    222
       * execution delay (in seconds) can be set. If that delay is non 0, the user is required to schedule any operation
    223
       * that is restricted to members of this role. The user will only be able to execute the operation after the delay has
    224
       * passed, before it has expired. During this period, admin and guardians can cancel the operation (see {cancel}).
    225
       *
    226
       * If the account has already been granted this role, the execution delay will be updated. This update is not
    227
       * immediate and follows the delay rules. For example, if a user currently has a delay of 3 hours, and this is
    228
       * called to reduce that delay to 1 hour, the new delay will take some time to take effect, enforcing that any
    229
       * operation executed in the 3 hours that follows this update was indeed scheduled before this update.
    230
       *
    231
       * Requirements:
    232
       *
    233
       * - the caller must be an admin for the role (see {getRoleAdmin})
    234
       * - granted role must not be the `PUBLIC_ROLE`
    235
       *
    236
       * Emits a {RoleGranted} event.
    237
       */
    238
      function grantRole(uint64 roleId, address account, uint32 executionDelay) external;
    239
    240
      /**
    241
       * @dev Remove an account from a role, with immediate effect. If the account does not have the role, this call has
    242
       * no effect.
    243
       *
    244
       * Requirements:
    245
       *
    246
       * - the caller must be an admin for the role (see {getRoleAdmin})
    247
       * - revoked role must not be the `PUBLIC_ROLE`
    248
       *
    249
       * Emits a {RoleRevoked} event if the account had the role.
    250
       */
    251
      function revokeRole(uint64 roleId, address account) external;
    252
    253
      /**
    254
       * @dev Renounce role permissions for the calling account with immediate effect. If the sender is not in
    255
       * the role this call has no effect.
    256
       *
    257
       * Requirements:
    258
       *
    259
       * - the caller must be `callerConfirmation`.
    260
       *
    261
       * Emits a {RoleRevoked} event if the account had the role.
    262
       */
    263
      function renounceRole(uint64 roleId, address callerConfirmation) external;
    264
    265
      /**
    266
       * @dev Change admin role for a given role.
    267
       *
    268
       * Requirements:
    269
       *
    270
       * - the caller must be a global admin
    271
       *
    272
       * Emits a {RoleAdminChanged} event
    273
       */
    274
      function setRoleAdmin(uint64 roleId, uint64 admin) external;
    275
    276
      /**
    277
       * @dev Change guardian role for a given role.
    278
       *
    279
       * Requirements:
    280
       *
    281
       * - the caller must be a global admin
    282
       *
    283
       * Emits a {RoleGuardianChanged} event
    284
       */
    285
      function setRoleGuardian(uint64 roleId, uint64 guardian) external;
    286
    287
      /**
    288
       * @dev Update the delay for granting a `roleId`.
    289
       *
    290
       * Requirements:
    291
       *
    292
       * - the caller must be a global admin
    293
       *
    294
       * Emits a {RoleGrantDelayChanged} event.
    295
       */
    296
      function setGrantDelay(uint64 roleId, uint32 newDelay) external;
    297
    298
      /**
    299
       * @dev Set the role required to call functions identified by the `selectors` in the `target` contract.
    300
       *
    301
       * Requirements:
    302
       *
    303
       * - the caller must be a global admin
    304
       *
    305
       * Emits a {TargetFunctionRoleUpdated} event per selector.
    306
       */
    307
      function setTargetFunctionRole(
    308
        address target,
    309
        bytes4[] calldata selectors,
    310
        uint64 roleId
    311
      ) external;
    312
    313
      /**
    314
       * @dev Set the delay for changing the configuration of a given target contract.
    315
       *
    316
       * Requirements:
    317
       *
    318
       * - the caller must be a global admin
    319
       *
    320
       * Emits a {TargetAdminDelayUpdated} event.
    321
       */
    322
      function setTargetAdminDelay(address target, uint32 newDelay) external;
    323
    324
      /**
    325
       * @dev Set the closed flag for a contract.
    326
       *
    327
       * Closing the manager itself won't disable access to admin methods to avoid locking the contract.
    328
       *
    329
       * Requirements:
    330
       *
    331
       * - the caller must be a global admin
    332
       *
    333
       * Emits a {TargetClosed} event.
    334
       */
    335
      function setTargetClosed(address target, bool closed) external;
    336
    337
      /**
    338
       * @dev Return the timepoint at which a scheduled operation will be ready for execution. This returns 0 if the
    339
       * operation is not yet scheduled, has expired, was executed, or was canceled.
    340
       */
    341
      function getSchedule(bytes32 id) external view returns (uint48);
    342
    343
      /**
    344
       * @dev Return the nonce for the latest scheduled operation with a given id. Returns 0 if the operation has never
    345
       * been scheduled.
    346
       */
    347
      function getNonce(bytes32 id) external view returns (uint32);
    348
    349
      /**
    350
       * @dev Schedule a delayed operation for future execution, and return the operation identifier. It is possible to
    351
       * choose the timestamp at which the operation becomes executable as long as it satisfies the execution delays
    352
       * required for the caller. The special value zero will automatically set the earliest possible time.
    353
       *
    354
       * Returns the `operationId` that was scheduled. Since this value is a hash of the parameters, it can reoccur when
    355
       * the same parameters are used; if this is relevant, the returned `nonce` can be used to uniquely identify this
    356
       * scheduled operation from other occurrences of the same `operationId` in invocations of {execute} and {cancel}.
    357
       *
    358
       * Emits a {OperationScheduled} event.
    359
       *
    360
       * NOTE: It is not possible to concurrently schedule more than one operation with the same `target` and `data`. If
    361
       * this is necessary, a random byte can be appended to `data` to act as a salt that will be ignored by the target
    362
       * contract if it is using standard Solidity ABI encoding.
    363
       */
    364
      function schedule(
    365
        address target,
    366
        bytes calldata data,
    367
        uint48 when
    368
      ) external returns (bytes32 operationId, uint32 nonce);
    369
    370
      /**
    371
       * @dev Execute a function that is delay restricted, provided it was properly scheduled beforehand, or the
    372
       * execution delay is 0.
    373
       *
    374
       * Returns the nonce that identifies the previously scheduled operation that is executed, or 0 if the
    375
       * operation wasn't previously scheduled (if the caller doesn't have an execution delay).
    376
       *
    377
       * Emits an {OperationExecuted} event only if the call was scheduled and delayed.
    378
       */
    379
      function execute(address target, bytes calldata data) external payable returns (uint32);
    380
    381
      /**
    382
       * @dev Cancel a scheduled (delayed) operation. Returns the nonce that identifies the previously scheduled
    383
       * operation that is cancelled.
    384
       *
    385
       * Requirements:
    386
       *
    387
       * - the caller must be the proposer, a guardian of the targeted function, or a global admin
    388
       *
    389
       * Emits a {OperationCanceled} event.
    390
       */
    391
      function cancel(address caller, address target, bytes calldata data) external returns (uint32);
    392
    393
      /**
    394
       * @dev Consume a scheduled operation targeting the caller. If such an operation exists, mark it as consumed
    395
       * (emit an {OperationExecuted} event and clean the state). Otherwise, throw an error.
    396
       *
    397
       * This is useful for contract that want to enforce that calls targeting them were scheduled on the manager,
    398
       * with all the verifications that it implies.
    399
       *
    400
       * Emit a {OperationExecuted} event.
    401
       */
    402
      function consumeScheduledOp(address caller, bytes calldata data) external;
    403
    404
      /**
    405
       * @dev Hashing function for delayed operations.
    406
       */
    407
      function hashOperation(
    408
        address caller,
    409
        address target,
    410
        bytes calldata data
    411
      ) external view returns (bytes32);
    412
    413
      /**
    414
       * @dev Changes the authority of a target managed by this manager instance.
    415
       *
    416
       * Requirements:
    417
       *
    418
       * - the caller must be a global admin
    419
       */
    420
      function updateAuthority(address target, address newAuthority) external;
    421
    }
    422
    100.0% src/dependencies/openzeppelin/IAuthority.sol
    Lines covered: 1 / 1 (100.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.4.0) (access/manager/IAuthority.sol)
    3
    4
    pragma solidity >=0.4.16;
    5
    6
    /**
    7
     * @dev Standard interface for permissioning originally defined in Dappsys.
    8
     */
    9
    interface IAuthority {
    10
      /**
    11
       * @dev Returns true if the caller can invoke on a target the function identified by a function selector.
    12
       */
    13
      function canCall(
    14
        address caller,
    15
        address target,
    16
        bytes4 selector
    17
      ) external view returns (bool allowed);
    18
    }
    19
    0.0% src/dependencies/openzeppelin/IBeacon.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.4.0) (proxy/beacon/IBeacon.sol)
    3
    4
    pragma solidity >=0.4.16;
    5
    6
    /**
    7
     * @dev This is the interface that {BeaconProxy} expects of its beacon.
    8
     */
    9
    interface IBeacon {
    10
      /**
    11
       * @dev Must return an address that can be used as a delegate call target.
    12
       *
    13
       * {UpgradeableBeacon} will check that this address is a contract.
    14
       */
    15
      function implementation() external view returns (address);
    16
    }
    17
    0.0% src/dependencies/openzeppelin/IERC1271.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1271.sol)
    3
    4
    pragma solidity >=0.5.0;
    5
    6
    /**
    7
     * @dev Interface of the ERC-1271 standard signature validation method for
    8
     * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].
    9
     */
    10
    interface IERC1271 {
    11
      /**
    12
       * @dev Should return whether the signature provided is valid for the provided data
    13
       * @param hash      Hash of the data to be signed
    14
       * @param signature Signature byte array associated with `hash`
    15
       */
    16
      function isValidSignature(
    17
        bytes32 hash,
    18
        bytes calldata signature
    19
      ) external view returns (bytes4 magicValue);
    20
    }
    21
    0.0% src/dependencies/openzeppelin/IERC1363.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1363.sol)
    3
    4
    pragma solidity >=0.6.2;
    5
    6
    import {IERC20} from './IERC20.sol';
    7
    import {IERC165} from './IERC165.sol';
    8
    9
    /**
    10
     * @title IERC1363
    11
     * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].
    12
     *
    13
     * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract
    14
     * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.
    15
     */
    16
    interface IERC1363 is IERC20, IERC165 {
    17
      /*
    18
       * Note: the ERC-165 identifier for this interface is 0xb0202a11.
    19
       * 0xb0202a11 ===
    20
       *   bytes4(keccak256('transferAndCall(address,uint256)')) ^
    21
       *   bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^
    22
       *   bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^
    23
       *   bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^
    24
       *   bytes4(keccak256('approveAndCall(address,uint256)')) ^
    25
       *   bytes4(keccak256('approveAndCall(address,uint256,bytes)'))
    26
       */
    27
    28
      /**
    29
       * @dev Moves a `value` amount of tokens from the caller's account to `to`
    30
       * and then calls {IERC1363Receiver-onTransferReceived} on `to`.
    31
       * @param to The address which you want to transfer to.
    32
       * @param value The amount of tokens to be transferred.
    33
       * @return A boolean value indicating whether the operation succeeded unless throwing.
    34
       */
    35
      function transferAndCall(address to, uint256 value) external returns (bool);
    36
    37
      /**
    38
       * @dev Moves a `value` amount of tokens from the caller's account to `to`
    39
       * and then calls {IERC1363Receiver-onTransferReceived} on `to`.
    40
       * @param to The address which you want to transfer to.
    41
       * @param value The amount of tokens to be transferred.
    42
       * @param data Additional data with no specified format, sent in call to `to`.
    43
       * @return A boolean value indicating whether the operation succeeded unless throwing.
    44
       */
    45
      function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);
    46
    47
      /**
    48
       * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
    49
       * and then calls {IERC1363Receiver-onTransferReceived} on `to`.
    50
       * @param from The address which you want to send tokens from.
    51
       * @param to The address which you want to transfer to.
    52
       * @param value The amount of tokens to be transferred.
    53
       * @return A boolean value indicating whether the operation succeeded unless throwing.
    54
       */
    55
      function transferFromAndCall(address from, address to, uint256 value) external returns (bool);
    56
    57
      /**
    58
       * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
    59
       * and then calls {IERC1363Receiver-onTransferReceived} on `to`.
    60
       * @param from The address which you want to send tokens from.
    61
       * @param to The address which you want to transfer to.
    62
       * @param value The amount of tokens to be transferred.
    63
       * @param data Additional data with no specified format, sent in call to `to`.
    64
       * @return A boolean value indicating whether the operation succeeded unless throwing.
    65
       */
    66
      function transferFromAndCall(
    67
        address from,
    68
        address to,
    69
        uint256 value,
    70
        bytes calldata data
    71
      ) external returns (bool);
    72
    73
      /**
    74
       * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
    75
       * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
    76
       * @param spender The address which will spend the funds.
    77
       * @param value The amount of tokens to be spent.
    78
       * @return A boolean value indicating whether the operation succeeded unless throwing.
    79
       */
    80
      function approveAndCall(address spender, uint256 value) external returns (bool);
    81
    82
      /**
    83
       * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
    84
       * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
    85
       * @param spender The address which will spend the funds.
    86
       * @param value The amount of tokens to be spent.
    87
       * @param data Additional data with no specified format, sent in call to `spender`.
    88
       * @return A boolean value indicating whether the operation succeeded unless throwing.
    89
       */
    90
      function approveAndCall(
    91
        address spender,
    92
        uint256 value,
    93
        bytes calldata data
    94
      ) external returns (bool);
    95
    }
    96
    0.0% src/dependencies/openzeppelin/IERC165.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)
    3
    4
    pragma solidity >=0.4.16;
    5
    6
    /**
    7
     * @dev Interface of the ERC-165 standard, as defined in the
    8
     * https://eips.ethereum.org/EIPS/eip-165[ERC].
    9
     *
    10
     * Implementers can declare support of contract interfaces, which can then be
    11
     * queried by others ({ERC165Checker}).
    12
     *
    13
     * For an implementation, see {ERC165}.
    14
     */
    15
    interface IERC165 {
    16
      /**
    17
       * @dev Returns true if this contract implements the interface defined by
    18
       * `interfaceId`. See the corresponding
    19
       * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
    20
       * to learn more about how these ids are created.
    21
       *
    22
       * This function call must use less than 30 000 gas.
    23
       */
    24
      function supportsInterface(bytes4 interfaceId) external view returns (bool);
    25
    }
    26
    0.0% src/dependencies/openzeppelin/IERC1967.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1967.sol)
    3
    4
    pragma solidity >=0.4.11;
    5
    6
    /**
    7
     * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.
    8
     */
    9
    interface IERC1967 {
    10
      /**
    11
       * @dev Emitted when the implementation is upgraded.
    12
       */
    13
      event Upgraded(address indexed implementation);
    14
    15
      /**
    16
       * @dev Emitted when the admin account has changed.
    17
       */
    18
      event AdminChanged(address previousAdmin, address newAdmin);
    19
    20
      /**
    21
       * @dev Emitted when the beacon is changed.
    22
       */
    23
      event BeaconUpgraded(address indexed beacon);
    24
    }
    25
    0.0% src/dependencies/openzeppelin/IERC20.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)
    3
    4
    pragma solidity >=0.4.16;
    5
    6
    /**
    7
     * @dev Interface of the ERC-20 standard as defined in the ERC.
    8
     */
    9
    interface IERC20 {
    10
      /**
    11
       * @dev Emitted when `value` tokens are moved from one account (`from`) to
    12
       * another (`to`).
    13
       *
    14
       * Note that `value` may be zero.
    15
       */
    16
      event Transfer(address indexed from, address indexed to, uint256 value);
    17
    18
      /**
    19
       * @dev Emitted when the allowance of a `spender` for an `owner` is set by
    20
       * a call to {approve}. `value` is the new allowance.
    21
       */
    22
      event Approval(address indexed owner, address indexed spender, uint256 value);
    23
    24
      /**
    25
       * @dev Returns the value of tokens in existence.
    26
       */
    27
      function totalSupply() external view returns (uint256);
    28
    29
      /**
    30
       * @dev Returns the value of tokens owned by `account`.
    31
       */
    32
      function balanceOf(address account) external view returns (uint256);
    33
    34
      /**
    35
       * @dev Moves a `value` amount of tokens from the caller's account to `to`.
    36
       *
    37
       * Returns a boolean value indicating whether the operation succeeded.
    38
       *
    39
       * Emits a {Transfer} event.
    40
       */
    41
      function transfer(address to, uint256 value) external returns (bool);
    42
    43
      /**
    44
       * @dev Returns the remaining number of tokens that `spender` will be
    45
       * allowed to spend on behalf of `owner` through {transferFrom}. This is
    46
       * zero by default.
    47
       *
    48
       * This value changes when {approve} or {transferFrom} are called.
    49
       */
    50
      function allowance(address owner, address spender) external view returns (uint256);
    51
    52
      /**
    53
       * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
    54
       * caller's tokens.
    55
       *
    56
       * Returns a boolean value indicating whether the operation succeeded.
    57
       *
    58
       * IMPORTANT: Beware that changing an allowance with this method brings the risk
    59
       * that someone may use both the old and the new allowance by unfortunate
    60
       * transaction ordering. One possible solution to mitigate this race
    61
       * condition is to first reduce the spender's allowance to 0 and set the
    62
       * desired value afterwards:
    63
       * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
    64
       *
    65
       * Emits an {Approval} event.
    66
       */
    67
      function approve(address spender, uint256 value) external returns (bool);
    68
    69
      /**
    70
       * @dev Moves a `value` amount of tokens from `from` to `to` using the
    71
       * allowance mechanism. `value` is then deducted from the caller's
    72
       * allowance.
    73
       *
    74
       * Returns a boolean value indicating whether the operation succeeded.
    75
       *
    76
       * Emits a {Transfer} event.
    77
       */
    78
      function transferFrom(address from, address to, uint256 value) external returns (bool);
    79
    }
    80
    0.0% src/dependencies/openzeppelin/IERC20Errors.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.4.0) (interfaces/draft-IERC6093.sol)
    3
    pragma solidity >=0.8.4;
    4
    5
    /**
    6
     * @dev Standard ERC-20 Errors
    7
     * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.
    8
     */
    9
    interface IERC20Errors {
    10
      /**
    11
       * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
    12
       * @param sender Address whose tokens are being transferred.
    13
       * @param balance Current balance for the interacting account.
    14
       * @param needed Minimum amount required to perform a transfer.
    15
       */
    16
      error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
    17
    18
      /**
    19
       * @dev Indicates a failure with the token `sender`. Used in transfers.
    20
       * @param sender Address whose tokens are being transferred.
    21
       */
    22
      error ERC20InvalidSender(address sender);
    23
    24
      /**
    25
       * @dev Indicates a failure with the token `receiver`. Used in transfers.
    26
       * @param receiver Address to which tokens are being transferred.
    27
       */
    28
      error ERC20InvalidReceiver(address receiver);
    29
    30
      /**
    31
       * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
    32
       * @param spender Address that may be allowed to operate on tokens without being their owner.
    33
       * @param allowance Amount of tokens a `spender` is allowed to operate with.
    34
       * @param needed Minimum amount required to perform a transfer.
    35
       */
    36
      error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
    37
    38
      /**
    39
       * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
    40
       * @param approver Address initiating an approval operation.
    41
       */
    42
      error ERC20InvalidApprover(address approver);
    43
    44
      /**
    45
       * @dev Indicates a failure with the `spender` to be approved. Used in approvals.
    46
       * @param spender Address that may be allowed to operate on tokens without being their owner.
    47
       */
    48
      error ERC20InvalidSpender(address spender);
    49
    }
    50
    0.0% src/dependencies/openzeppelin/IERC20Metadata.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/IERC20Metadata.sol)
    3
    4
    pragma solidity >=0.6.2;
    5
    6
    import {IERC20} from './IERC20.sol';
    7
    8
    /**
    9
     * @dev Interface for the optional metadata functions from the ERC-20 standard.
    10
     */
    11
    interface IERC20Metadata is IERC20 {
    12
      /**
    13
       * @dev Returns the name of the token.
    14
       */
    15
      function name() external view returns (string memory);
    16
    17
      /**
    18
       * @dev Returns the symbol of the token.
    19
       */
    20
      function symbol() external view returns (string memory);
    21
    22
      /**
    23
       * @dev Returns the decimals places of the token.
    24
       */
    25
      function decimals() external view returns (uint8);
    26
    }
    27
    0.0% src/dependencies/openzeppelin/IERC20Permit.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/IERC20Permit.sol)
    3
    4
    pragma solidity >=0.4.16;
    5
    6
    /**
    7
     * @dev Interface of the ERC-20 Permit extension allowing approvals to be made via signatures, as defined in
    8
     * https://eips.ethereum.org/EIPS/eip-2612[ERC-2612].
    9
     *
    10
     * Adds the {permit} method, which can be used to change an account's ERC-20 allowance (see {IERC20-allowance}) by
    11
     * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
    12
     * need to send a transaction, and thus is not required to hold Ether at all.
    13
     *
    14
     * ==== Security Considerations
    15
     *
    16
     * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
    17
     * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
    18
     * considered as an intention to spend the allowance in any specific way. The second is that because permits have
    19
     * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
    20
     * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
    21
     * generally recommended is:
    22
     *
    23
     * ```solidity
    24
     * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
    25
     *     try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
    26
     *     doThing(..., value);
    27
     * }
    28
     *
    29
     * function doThing(..., uint256 value) public {
    30
     *     token.safeTransferFrom(msg.sender, address(this), value);
    31
     *     ...
    32
     * }
    33
     * ```
    34
     *
    35
     * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
    36
     * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
    37
     * {SafeERC20-safeTransferFrom}).
    38
     *
    39
     * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
    40
     * contracts should have entry points that don't rely on permit.
    41
     */
    42
    interface IERC20Permit {
    43
      /**
    44
       * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
    45
       * given ``owner``'s signed approval.
    46
       *
    47
       * IMPORTANT: The same issues {IERC20-approve} has related to transaction
    48
       * ordering also apply here.
    49
       *
    50
       * Emits an {Approval} event.
    51
       *
    52
       * Requirements:
    53
       *
    54
       * - `spender` cannot be the zero address.
    55
       * - `deadline` must be a timestamp in the future.
    56
       * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
    57
       * over the EIP712-formatted function arguments.
    58
       * - the signature must use ``owner``'s current nonce (see {nonces}).
    59
       *
    60
       * For more information on the signature format, see the
    61
       * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
    62
       * section].
    63
       *
    64
       * CAUTION: See Security Considerations above.
    65
       */
    66
      function permit(
    67
        address owner,
    68
        address spender,
    69
        uint256 value,
    70
        uint256 deadline,
    71
        uint8 v,
    72
        bytes32 r,
    73
        bytes32 s
    74
      ) external;
    75
    76
      /**
    77
       * @dev Returns the current nonce for `owner`. This value must be
    78
       * included whenever a signature is generated for {permit}.
    79
       *
    80
       * Every successful call to {permit} increases ``owner``'s nonce by one. This
    81
       * prevents a signature from being used multiple times.
    82
       */
    83
      function nonces(address owner) external view returns (uint256);
    84
    85
      /**
    86
       * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
    87
       */
    88
      // solhint-disable-next-line func-name-mixedcase
    89
      function DOMAIN_SEPARATOR() external view returns (bytes32);
    90
    }
    91
    0.0% src/dependencies/openzeppelin/IERC5267.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC5267.sol)
    3
    4
    pragma solidity >=0.4.16;
    5
    6
    interface IERC5267 {
    7
      /**
    8
       * @dev MAY be emitted to signal that the domain could have changed.
    9
       */
    10
      event EIP712DomainChanged();
    11
    12
      /**
    13
       * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712
    14
       * signature.
    15
       */
    16
      function eip712Domain()
    17
        external
    18
        view
    19
        returns (
    20
          bytes1 fields,
    21
          string memory name,
    22
          string memory version,
    23
          uint256 chainId,
    24
          address verifyingContract,
    25
          bytes32 salt,
    26
          uint256[] memory extensions
    27
        );
    28
    }
    29
    0.0% src/dependencies/openzeppelin/IERC7913.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC7913.sol)
    3
    4
    pragma solidity >=0.5.0;
    5
    6
    /**
    7
     * @dev Signature verifier interface.
    8
     */
    9
    interface IERC7913SignatureVerifier {
    10
      /**
    11
       * @dev Verifies `signature` as a valid signature of `hash` by `key`.
    12
       *
    13
       * MUST return the bytes4 magic value IERC7913SignatureVerifier.verify.selector if the signature is valid.
    14
       * SHOULD return 0xffffffff or revert if the signature is not valid.
    15
       * SHOULD return 0xffffffff or revert if the key is empty
    16
       */
    17
      function verify(
    18
        bytes calldata key,
    19
        bytes32 hash,
    20
        bytes calldata signature
    21
      ) external view returns (bytes4);
    22
    }
    23
    0.0% src/dependencies/openzeppelin/Math.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.3.0) (utils/math/Math.sol)
    3
    4
    pragma solidity ^0.8.20;
    5
    6
    import {Panic} from './Panic.sol';
    7
    import {SafeCast} from './SafeCast.sol';
    8
    9
    /**
    10
     * @dev Standard math utilities missing in the Solidity language.
    11
     */
    12
    library Math {
    13
      enum Rounding {
    14
        Floor, // Toward negative infinity
    15
        Ceil, // Toward positive infinity
    16
        Trunc, // Toward zero
    17
        Expand // Away from zero
    18
      }
    19
    20
      /**
    21
       * @dev Return the 512-bit addition of two uint256.
    22
       *
    23
       * The result is stored in two 256 variables such that sum = high * 2²⁵⁶ + low.
    24
       */
    25
      function add512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {
    26
        assembly ('memory-safe') {
    27
          low := add(a, b)
    28
          high := lt(low, a)
    29
        }
    30
      }
    31
    32
      /**
    33
       * @dev Return the 512-bit multiplication of two uint256.
    34
       *
    35
       * The result is stored in two 256 variables such that product = high * 2²⁵⁶ + low.
    36
       */
    37
      function mul512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {
    38
        // 512-bit multiply [high low] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use
    39
        // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
    40
        // variables such that product = high * 2²⁵⁶ + low.
    41
        assembly ('memory-safe') {
    42
          let mm := mulmod(a, b, not(0))
    43
          low := mul(a, b)
    44
          high := sub(sub(mm, low), lt(mm, low))
    45
        }
    46
      }
    47
    48
      /**
    49
       * @dev Returns the addition of two unsigned integers, with a success flag (no overflow).
    50
       */
    51
      function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
    52
        unchecked {
    53
          uint256 c = a + b;
    54
          success = c >= a;
    55
          result = c * SafeCast.toUint(success);
    56
        }
    57
      }
    58
    59
      /**
    60
       * @dev Returns the subtraction of two unsigned integers, with a success flag (no overflow).
    61
       */
    62
      function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
    63
        unchecked {
    64
          uint256 c = a - b;
    65
          success = c <= a;
    66
          result = c * SafeCast.toUint(success);
    67
        }
    68
      }
    69
    70
      /**
    71
       * @dev Returns the multiplication of two unsigned integers, with a success flag (no overflow).
    72
       */
    73
      function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
    74
        unchecked {
    75
          uint256 c = a * b;
    76
          assembly ('memory-safe') {
    77
            // Only true when the multiplication doesn't overflow
    78
            // (c / a == b) || (a == 0)
    79
            success := or(eq(div(c, a), b), iszero(a))
    80
          }
    81
          // equivalent to: success ? c : 0
    82
          result = c * SafeCast.toUint(success);
    83
        }
    84
      }
    85
    86
      /**
    87
       * @dev Returns the division of two unsigned integers, with a success flag (no division by zero).
    88
       */
    89
      function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
    90
        unchecked {
    91
          success = b > 0;
    92
          assembly ('memory-safe') {
    93
            // The `DIV` opcode returns zero when the denominator is 0.
    94
            result := div(a, b)
    95
          }
    96
        }
    97
      }
    98
    99
      /**
    100
       * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero).
    101
       */
    102
      function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
    103
        unchecked {
    104
          success = b > 0;
    105
          assembly ('memory-safe') {
    106
            // The `MOD` opcode returns zero when the denominator is 0.
    107
            result := mod(a, b)
    108
          }
    109
        }
    110
      }
    111
    112
      /**
    113
       * @dev Unsigned saturating addition, bounds to `2²⁵⁶ - 1` instead of overflowing.
    114
       */
    115
      function saturatingAdd(uint256 a, uint256 b) internal pure returns (uint256) {
    116
        (bool success, uint256 result) = tryAdd(a, b);
    117
        return ternary(success, result, type(uint256).max);
    118
      }
    119
    120
      /**
    121
       * @dev Unsigned saturating subtraction, bounds to zero instead of overflowing.
    122
       */
    123
      function saturatingSub(uint256 a, uint256 b) internal pure returns (uint256) {
    124
        (, uint256 result) = trySub(a, b);
    125
        return result;
    126
      }
    127
    128
      /**
    129
       * @dev Unsigned saturating multiplication, bounds to `2²⁵⁶ - 1` instead of overflowing.
    130
       */
    131
      function saturatingMul(uint256 a, uint256 b) internal pure returns (uint256) {
    132
        (bool success, uint256 result) = tryMul(a, b);
    133
        return ternary(success, result, type(uint256).max);
    134
      }
    135
    136
      /**
    137
       * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant.
    138
       *
    139
       * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone.
    140
       * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute
    141
       * one branch when needed, making this function more expensive.
    142
       */
    143
      function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) {
    144
        unchecked {
    145
          // branchless ternary works because:
    146
          // b ^ (a ^ b) == a
    147
          // b ^ 0 == b
    148
          return b ^ ((a ^ b) * SafeCast.toUint(condition));
    149
        }
    150
      }
    151
    152
      /**
    153
       * @dev Returns the largest of two numbers.
    154
       */
    155
      function max(uint256 a, uint256 b) internal pure returns (uint256) {
    156
        return ternary(a > b, a, b);
    157
      }
    158
    159
      /**
    160
       * @dev Returns the smallest of two numbers.
    161
       */
    162
      function min(uint256 a, uint256 b) internal pure returns (uint256) {
    163
        return ternary(a < b, a, b);
    164
      }
    165
    166
      /**
    167
       * @dev Returns the average of two numbers. The result is rounded towards
    168
       * zero.
    169
       */
    170
      function average(uint256 a, uint256 b) internal pure returns (uint256) {
    171
        // (a + b) / 2 can overflow.
    172
        return (a & b) + (a ^ b) / 2;
    173
      }
    174
    175
      /**
    176
       * @dev Returns the ceiling of the division of two numbers.
    177
       *
    178
       * This differs from standard division with `/` in that it rounds towards infinity instead
    179
       * of rounding towards zero.
    180
       */
    181
      function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
    182
        if (b == 0) {
    183
          // Guarantee the same behavior as in a regular Solidity division.
    184
          Panic.panic(Panic.DIVISION_BY_ZERO);
    185
        }
    186
    187
        // The following calculation ensures accurate ceiling division without overflow.
    188
        // Since a is non-zero, (a - 1) / b will not overflow.
    189
        // The largest possible result occurs when (a - 1) / b is type(uint256).max,
    190
        // but the largest value we can obtain is type(uint256).max - 1, which happens
    191
        // when a = type(uint256).max and b = 1.
    192
        unchecked {
    193
          return SafeCast.toUint(a > 0) * ((a - 1) / b + 1);
    194
        }
    195
      }
    196
    197
      /**
    198
       * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or
    199
       * denominator == 0.
    200
       *
    201
       * Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by
    202
       * Uniswap Labs also under MIT license.
    203
       */
    204
      function mulDiv(
    205
        uint256 x,
    206
        uint256 y,
    207
        uint256 denominator
    208
      ) internal pure returns (uint256 result) {
    209
        unchecked {
    210
          (uint256 high, uint256 low) = mul512(x, y);
    211
    212
          // Handle non-overflow cases, 256 by 256 division.
    213
          if (high == 0) {
    214
            // Solidity will revert if denominator == 0, unlike the div opcode on its own.
    215
            // The surrounding unchecked block does not change this fact.
    216
            // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
    217
            return low / denominator;
    218
          }
    219
    220
          // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0.
    221
          if (denominator <= high) {
    222
            Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW));
    223
          }
    224
    225
          ///////////////////////////////////////////////
    226
          // 512 by 256 division.
    227
          ///////////////////////////////////////////////
    228
    229
          // Make division exact by subtracting the remainder from [high low].
    230
          uint256 remainder;
    231
          assembly ('memory-safe') {
    232
            // Compute remainder using mulmod.
    233
            remainder := mulmod(x, y, denominator)
    234
    235
            // Subtract 256 bit number from 512 bit number.
    236
            high := sub(high, gt(remainder, low))
    237
            low := sub(low, remainder)
    238
          }
    239
    240
          // Factor powers of two out of denominator and compute largest power of two divisor of denominator.
    241
          // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.
    242
    243
          uint256 twos = denominator & (0 - denominator);
    244
          assembly ('memory-safe') {
    245
            // Divide denominator by twos.
    246
            denominator := div(denominator, twos)
    247
    248
            // Divide [high low] by twos.
    249
            low := div(low, twos)
    250
    251
            // Flip twos such that it is 2²⁵⁶ / twos. If twos is zero, then it becomes one.
    252
            twos := add(div(sub(0, twos), twos), 1)
    253
          }
    254
    255
          // Shift in bits from high into low.
    256
          low |= high * twos;
    257
    258
          // Invert denominator mod 2²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such
    259
          // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for
    260
          // four bits. That is, denominator * inv ≡ 1 mod 2⁴.
    261
          uint256 inverse = (3 * denominator) ^ 2;
    262
    263
          // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also
    264
          // works in modular arithmetic, doubling the correct bits in each step.
    265
          inverse *= 2 - denominator * inverse; // inverse mod 2⁸
    266
          inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶
    267
          inverse *= 2 - denominator * inverse; // inverse mod 2³²
    268
          inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴
    269
          inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸
    270
          inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶
    271
    272
          // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
    273
          // This will give us the correct result modulo 2²⁵⁶. Since the preconditions guarantee that the outcome is
    274
          // less than 2²⁵⁶, this is the final result. We don't need to compute the high bits of the result and high
    275
          // is no longer required.
    276
          result = low * inverse;
    277
          return result;
    278
        }
    279
      }
    280
    281
      /**
    282
       * @dev Calculates x * y / denominator with full precision, following the selected rounding direction.
    283
       */
    284
      function mulDiv(
    285
        uint256 x,
    286
        uint256 y,
    287
        uint256 denominator,
    288
        Rounding rounding
    289
      ) internal pure returns (uint256) {
    290
        return
    291
          mulDiv(x, y, denominator) +
    292
          SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0);
    293
      }
    294
    295
      /**
    296
       * @dev Calculates floor(x * y >> n) with full precision. Throws if result overflows a uint256.
    297
       */
    298
      function mulShr(uint256 x, uint256 y, uint8 n) internal pure returns (uint256 result) {
    299
        unchecked {
    300
          (uint256 high, uint256 low) = mul512(x, y);
    301
          if (high >= 1 << n) {
    302
            Panic.panic(Panic.UNDER_OVERFLOW);
    303
          }
    304
          return (high << (256 - n)) | (low >> n);
    305
        }
    306
      }
    307
    308
      /**
    309
       * @dev Calculates x * y >> n with full precision, following the selected rounding direction.
    310
       */
    311
      function mulShr(
    312
        uint256 x,
    313
        uint256 y,
    314
        uint8 n,
    315
        Rounding rounding
    316
      ) internal pure returns (uint256) {
    317
        return
    318
          mulShr(x, y, n) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, 1 << n) > 0);
    319
      }
    320
    321
      /**
    322
       * @dev Calculate the modular multiplicative inverse of a number in Z/nZ.
    323
       *
    324
       * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0.
    325
       * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible.
    326
       *
    327
       * If the input value is not inversible, 0 is returned.
    328
       *
    329
       * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the
    330
       * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}.
    331
       */
    332
      function invMod(uint256 a, uint256 n) internal pure returns (uint256) {
    333
        unchecked {
    334
          if (n == 0) return 0;
    335
    336
          // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version)
    337
          // Used to compute integers x and y such that: ax + ny = gcd(a, n).
    338
          // When the gcd is 1, then the inverse of a modulo n exists and it's x.
    339
          // ax + ny = 1
    340
          // ax = 1 + (-y)n
    341
          // ax ≡ 1 (mod n) # x is the inverse of a modulo n
    342
    343
          // If the remainder is 0 the gcd is n right away.
    344
          uint256 remainder = a % n;
    345
          uint256 gcd = n;
    346
    347
          // Therefore the initial coefficients are:
    348
          // ax + ny = gcd(a, n) = n
    349
          // 0a + 1n = n
    350
          int256 x = 0;
    351
          int256 y = 1;
    352
    353
          while (remainder != 0) {
    354
            uint256 quotient = gcd / remainder;
    355
    356
            (gcd, remainder) = (
    357
              // The old remainder is the next gcd to try.
    358
              remainder,
    359
              // Compute the next remainder.
    360
              // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd
    361
              // where gcd is at most n (capped to type(uint256).max)
    362
              gcd - remainder * quotient
    363
            );
    364
    365
            (x, y) = (
    366
              // Increment the coefficient of a.
    367
              y,
    368
              // Decrement the coefficient of n.
    369
              // Can overflow, but the result is casted to uint256 so that the
    370
              // next value of y is "wrapped around" to a value between 0 and n - 1.
    371
              x - y * int256(quotient)
    372
            );
    373
          }
    374
    375
          if (gcd != 1) return 0; // No inverse exists.
    376
          return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative.
    377
        }
    378
      }
    379
    380
      /**
    381
       * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`.
    382
       *
    383
       * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is
    384
       * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that
    385
       * `a**(p-2)` is the modular multiplicative inverse of a in Fp.
    386
       *
    387
       * NOTE: this function does NOT check that `p` is a prime greater than `2`.
    388
       */
    389
      function invModPrime(uint256 a, uint256 p) internal view returns (uint256) {
    390
        unchecked {
    391
          return Math.modExp(a, p - 2, p);
    392
        }
    393
      }
    394
    395
      /**
    396
       * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m)
    397
       *
    398
       * Requirements:
    399
       * - modulus can't be zero
    400
       * - underlying staticcall to precompile must succeed
    401
       *
    402
       * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make
    403
       * sure the chain you're using it on supports the precompiled contract for modular exponentiation
    404
       * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise,
    405
       * the underlying function will succeed given the lack of a revert, but the result may be incorrectly
    406
       * interpreted as 0.
    407
       */
    408
      function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) {
    409
        (bool success, uint256 result) = tryModExp(b, e, m);
    410
        if (!success) {
    411
          Panic.panic(Panic.DIVISION_BY_ZERO);
    412
        }
    413
        return result;
    414
      }
    415
    416
      /**
    417
       * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m).
    418
       * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying
    419
       * to operate modulo 0 or if the underlying precompile reverted.
    420
       *
    421
       * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain
    422
       * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in
    423
       * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack
    424
       * of a revert, but the result may be incorrectly interpreted as 0.
    425
       */
    426
      function tryModExp(
    427
        uint256 b,
    428
        uint256 e,
    429
        uint256 m
    430
      ) internal view returns (bool success, uint256 result) {
    431
        if (m == 0) return (false, 0);
    432
        assembly ('memory-safe') {
    433
          let ptr := mload(0x40)
    434
          // | Offset    | Content    | Content (Hex)                                                      |
    435
          // |-----------|------------|--------------------------------------------------------------------|
    436
          // | 0x00:0x1f | size of b  | 0x0000000000000000000000000000000000000000000000000000000000000020 |
    437
          // | 0x20:0x3f | size of e  | 0x0000000000000000000000000000000000000000000000000000000000000020 |
    438
          // | 0x40:0x5f | size of m  | 0x0000000000000000000000000000000000000000000000000000000000000020 |
    439
          // | 0x60:0x7f | value of b | 0x<.............................................................b> |
    440
          // | 0x80:0x9f | value of e | 0x<.............................................................e> |
    441
          // | 0xa0:0xbf | value of m | 0x<.............................................................m> |
    442
          mstore(ptr, 0x20)
    443
          mstore(add(ptr, 0x20), 0x20)
    444
          mstore(add(ptr, 0x40), 0x20)
    445
          mstore(add(ptr, 0x60), b)
    446
          mstore(add(ptr, 0x80), e)
    447
          mstore(add(ptr, 0xa0), m)
    448
    449
          // Given the result < m, it's guaranteed to fit in 32 bytes,
    450
          // so we can use the memory scratch space located at offset 0.
    451
          success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20)
    452
          result := mload(0x00)
    453
        }
    454
      }
    455
    456
      /**
    457
       * @dev Variant of {modExp} that supports inputs of arbitrary length.
    458
       */
    459
      function modExp(
    460
        bytes memory b,
    461
        bytes memory e,
    462
        bytes memory m
    463
      ) internal view returns (bytes memory) {
    464
        (bool success, bytes memory result) = tryModExp(b, e, m);
    465
        if (!success) {
    466
          Panic.panic(Panic.DIVISION_BY_ZERO);
    467
        }
    468
        return result;
    469
      }
    470
    471
      /**
    472
       * @dev Variant of {tryModExp} that supports inputs of arbitrary length.
    473
       */
    474
      function tryModExp(
    475
        bytes memory b,
    476
        bytes memory e,
    477
        bytes memory m
    478
      ) internal view returns (bool success, bytes memory result) {
    479
        if (_zeroBytes(m)) return (false, new bytes(0));
    480
    481
        uint256 mLen = m.length;
    482
    483
        // Encode call args in result and move the free memory pointer
    484
        result = abi.encodePacked(b.length, e.length, mLen, b, e, m);
    485
    486
        assembly ('memory-safe') {
    487
          let dataPtr := add(result, 0x20)
    488
          // Write result on top of args to avoid allocating extra memory.
    489
          success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen)
    490
          // Overwrite the length.
    491
          // result.length > returndatasize() is guaranteed because returndatasize() == m.length
    492
          mstore(result, mLen)
    493
          // Set the memory pointer after the returned data.
    494
          mstore(0x40, add(dataPtr, mLen))
    495
        }
    496
      }
    497
    498
      /**
    499
       * @dev Returns whether the provided byte array is zero.
    500
       */
    501
      function _zeroBytes(bytes memory byteArray) private pure returns (bool) {
    502
        for (uint256 i = 0; i < byteArray.length; ++i) {
    503
          if (byteArray[i] != 0) {
    504
            return false;
    505
          }
    506
        }
    507
        return true;
    508
      }
    509
    510
      /**
    511
       * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded
    512
       * towards zero.
    513
       *
    514
       * This method is based on Newton's method for computing square roots; the algorithm is restricted to only
    515
       * using integer operations.
    516
       */
    517
      function sqrt(uint256 a) internal pure returns (uint256) {
    518
        unchecked {
    519
          // Take care of easy edge cases when a == 0 or a == 1
    520
          if (a <= 1) {
    521
            return a;
    522
          }
    523
    524
          // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a
    525
          // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between
    526
          // the current value as `ε_n = | x_n - sqrt(a) |`.
    527
          //
    528
          // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root
    529
          // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is
    530
          // bigger than any uint256.
    531
          //
    532
          // By noticing that
    533
          // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)`
    534
          // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar
    535
          // to the msb function.
    536
          uint256 aa = a;
    537
          uint256 xn = 1;
    538
    539
          if (aa >= (1 << 128)) {
    540
            aa >>= 128;
    541
            xn <<= 64;
    542
          }
    543
          if (aa >= (1 << 64)) {
    544
            aa >>= 64;
    545
            xn <<= 32;
    546
          }
    547
          if (aa >= (1 << 32)) {
    548
            aa >>= 32;
    549
            xn <<= 16;
    550
          }
    551
          if (aa >= (1 << 16)) {
    552
            aa >>= 16;
    553
            xn <<= 8;
    554
          }
    555
          if (aa >= (1 << 8)) {
    556
            aa >>= 8;
    557
            xn <<= 4;
    558
          }
    559
          if (aa >= (1 << 4)) {
    560
            aa >>= 4;
    561
            xn <<= 2;
    562
          }
    563
          if (aa >= (1 << 2)) {
    564
            xn <<= 1;
    565
          }
    566
    567
          // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1).
    568
          //
    569
          // We can refine our estimation by noticing that the middle of that interval minimizes the error.
    570
          // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2).
    571
          // This is going to be our x_0 (and ε_0)
    572
          xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2)
    573
    574
          // From here, Newton's method give us:
    575
          // x_{n+1} = (x_n + a / x_n) / 2
    576
          //
    577
          // One should note that:
    578
          // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a
    579
          //              = ((x_n² + a) / (2 * x_n))² - a
    580
          //              = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a
    581
          //              = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²)
    582
          //              = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²)
    583
          //              = (x_n² - a)² / (2 * x_n)²
    584
          //              = ((x_n² - a) / (2 * x_n))²
    585
          //              ≥ 0
    586
          // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n
    587
          //
    588
          // This gives us the proof of quadratic convergence of the sequence:
    589
          // ε_{n+1} = | x_{n+1} - sqrt(a) |
    590
          //         = | (x_n + a / x_n) / 2 - sqrt(a) |
    591
          //         = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) |
    592
          //         = | (x_n - sqrt(a))² / (2 * x_n) |
    593
          //         = | ε_n² / (2 * x_n) |
    594
          //         = ε_n² / | (2 * x_n) |
    595
          //
    596
          // For the first iteration, we have a special case where x_0 is known:
    597
          // ε_1 = ε_0² / | (2 * x_0) |
    598
          //     ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2)))
    599
          //     ≤ 2**(2*e-4) / (3 * 2**(e-1))
    600
          //     ≤ 2**(e-3) / 3
    601
          //     ≤ 2**(e-3-log2(3))
    602
          //     ≤ 2**(e-4.5)
    603
          //
    604
          // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n:
    605
          // ε_{n+1} = ε_n² / | (2 * x_n) |
    606
          //         ≤ (2**(e-k))² / (2 * 2**(e-1))
    607
          //         ≤ 2**(2*e-2*k) / 2**e
    608
          //         ≤ 2**(e-2*k)
    609
          xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5)  -- special case, see above
    610
          xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9)    -- general case with k = 4.5
    611
          xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18)   -- general case with k = 9
    612
          xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36)   -- general case with k = 18
    613
          xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72)   -- general case with k = 36
    614
          xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144)  -- general case with k = 72
    615
    616
          // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision
    617
          // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either
    618
          // sqrt(a) or sqrt(a) + 1.
    619
          return xn - SafeCast.toUint(xn > a / xn);
    620
        }
    621
      }
    622
    623
      /**
    624
       * @dev Calculates sqrt(a), following the selected rounding direction.
    625
       */
    626
      function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
    627
        unchecked {
    628
          uint256 result = sqrt(a);
    629
          return result + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a);
    630
        }
    631
      }
    632
    633
      /**
    634
       * @dev Return the log in base 2 of a positive value rounded towards zero.
    635
       * Returns 0 if given 0.
    636
       */
    637
      function log2(uint256 x) internal pure returns (uint256 r) {
    638
        // If value has upper 128 bits set, log2 result is at least 128
    639
        r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;
    640
        // If upper 64 bits of 128-bit half set, add 64 to result
    641
        r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;
    642
        // If upper 32 bits of 64-bit half set, add 32 to result
    643
        r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;
    644
        // If upper 16 bits of 32-bit half set, add 16 to result
    645
        r |= SafeCast.toUint((x >> r) > 0xffff) << 4;
    646
        // If upper 8 bits of 16-bit half set, add 8 to result
    647
        r |= SafeCast.toUint((x >> r) > 0xff) << 3;
    648
        // If upper 4 bits of 8-bit half set, add 4 to result
    649
        r |= SafeCast.toUint((x >> r) > 0xf) << 2;
    650
    651
        // Shifts value right by the current result and use it as an index into this lookup table:
    652
        //
    653
        // | x (4 bits) |  index  | table[index] = MSB position |
    654
        // |------------|---------|-----------------------------|
    655
        // |    0000    |    0    |        table[0] = 0         |
    656
        // |    0001    |    1    |        table[1] = 0         |
    657
        // |    0010    |    2    |        table[2] = 1         |
    658
        // |    0011    |    3    |        table[3] = 1         |
    659
        // |    0100    |    4    |        table[4] = 2         |
    660
        // |    0101    |    5    |        table[5] = 2         |
    661
        // |    0110    |    6    |        table[6] = 2         |
    662
        // |    0111    |    7    |        table[7] = 2         |
    663
        // |    1000    |    8    |        table[8] = 3         |
    664
        // |    1001    |    9    |        table[9] = 3         |
    665
        // |    1010    |   10    |        table[10] = 3        |
    666
        // |    1011    |   11    |        table[11] = 3        |
    667
        // |    1100    |   12    |        table[12] = 3        |
    668
        // |    1101    |   13    |        table[13] = 3        |
    669
        // |    1110    |   14    |        table[14] = 3        |
    670
        // |    1111    |   15    |        table[15] = 3        |
    671
        //
    672
        // The lookup table is represented as a 32-byte value with the MSB positions for 0-15 in the last 16 bytes.
    673
        assembly ('memory-safe') {
    674
          r := or(
    675
            r,
    676
            byte(shr(r, x), 0x0000010102020202030303030303030300000000000000000000000000000000)
    677
          )
    678
        }
    679
      }
    680
    681
      /**
    682
       * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
    683
       * Returns 0 if given 0.
    684
       */
    685
      function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
    686
        unchecked {
    687
          uint256 result = log2(value);
    688
          return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value);
    689
        }
    690
      }
    691
    692
      /**
    693
       * @dev Return the log in base 10 of a positive value rounded towards zero.
    694
       * Returns 0 if given 0.
    695
       */
    696
      function log10(uint256 value) internal pure returns (uint256) {
    697
        uint256 result = 0;
    698
        unchecked {
    699
          if (value >= 10 ** 64) {
    700
            value /= 10 ** 64;
    701
            result += 64;
    702
          }
    703
          if (value >= 10 ** 32) {
    704
            value /= 10 ** 32;
    705
            result += 32;
    706
          }
    707
          if (value >= 10 ** 16) {
    708
            value /= 10 ** 16;
    709
            result += 16;
    710
          }
    711
          if (value >= 10 ** 8) {
    712
            value /= 10 ** 8;
    713
            result += 8;
    714
          }
    715
          if (value >= 10 ** 4) {
    716
            value /= 10 ** 4;
    717
            result += 4;
    718
          }
    719
          if (value >= 10 ** 2) {
    720
            value /= 10 ** 2;
    721
            result += 2;
    722
          }
    723
          if (value >= 10 ** 1) {
    724
            result += 1;
    725
          }
    726
        }
    727
        return result;
    728
      }
    729
    730
      /**
    731
       * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
    732
       * Returns 0 if given 0.
    733
       */
    734
      function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
    735
        unchecked {
    736
          uint256 result = log10(value);
    737
          return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value);
    738
        }
    739
      }
    740
    741
      /**
    742
       * @dev Return the log in base 256 of a positive value rounded towards zero.
    743
       * Returns 0 if given 0.
    744
       *
    745
       * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
    746
       */
    747
      function log256(uint256 x) internal pure returns (uint256 r) {
    748
        // If value has upper 128 bits set, log2 result is at least 128
    749
        r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;
    750
        // If upper 64 bits of 128-bit half set, add 64 to result
    751
        r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;
    752
        // If upper 32 bits of 64-bit half set, add 32 to result
    753
        r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;
    754
        // If upper 16 bits of 32-bit half set, add 16 to result
    755
        r |= SafeCast.toUint((x >> r) > 0xffff) << 4;
    756
        // Add 1 if upper 8 bits of 16-bit half set, and divide accumulated result by 8
    757
        return (r >> 3) | SafeCast.toUint((x >> r) > 0xff);
    758
      }
    759
    760
      /**
    761
       * @dev Return the log in base 256, following the selected rounding direction, of a positive value.
    762
       * Returns 0 if given 0.
    763
       */
    764
      function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
    765
        unchecked {
    766
          uint256 result = log256(value);
    767
          return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value);
    768
        }
    769
      }
    770
    771
      /**
    772
       * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
    773
       */
    774
      function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
    775
        return uint8(rounding) % 2 == 1;
    776
      }
    777
    }
    778
    0.0% src/dependencies/openzeppelin/Multicall.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.3.0) (utils/Multicall.sol)
    3
    4
    pragma solidity ^0.8.20;
    5
    6
    import {Address} from './Address.sol';
    7
    import {Context} from './Context.sol';
    8
    9
    /**
    10
     * @dev Provides a function to batch together multiple calls in a single external call.
    11
     *
    12
     * Consider any assumption about calldata validation performed by the sender may be violated if it's not especially
    13
     * careful about sending transactions invoking {multicall}. For example, a relay address that filters function
    14
     * selectors won't filter calls nested within a {multicall} operation.
    15
     *
    16
     * NOTE: Since 5.0.1 and 4.9.4, this contract identifies non-canonical contexts (i.e. `msg.sender` is not {Context-_msgSender}).
    17
     * If a non-canonical context is identified, the following self `delegatecall` appends the last bytes of `msg.data`
    18
     * to the subcall. This makes it safe to use with {ERC2771Context}. Contexts that don't affect the resolution of
    19
     * {Context-_msgSender} are not propagated to subcalls.
    20
     */
    21
    abstract contract Multicall is Context {
    22
      /**
    23
       * @dev Receives and executes a batch of function calls on this contract.
    24
       * @custom:oz-upgrades-unsafe-allow-reachable delegatecall
    25
       */
    26
      function multicall(bytes[] calldata data) external virtual returns (bytes[] memory results) {
    27
        bytes memory context = msg.sender == _msgSender()
    28
          ? new bytes(0)
    29
          : msg.data[msg.data.length - _contextSuffixLength():];
    30
    31
        results = new bytes[](data.length);
    32
        for (uint256 i = 0; i < data.length; i++) {
    33
          results[i] = Address.functionDelegateCall(address(this), bytes.concat(data[i], context));
    34
        }
    35
        return results;
    36
      }
    37
    }
    38
    0.0% src/dependencies/openzeppelin/Ownable.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
    3
    4
    pragma solidity ^0.8.20;
    5
    6
    import {Context} from './Context.sol';
    7
    8
    /**
    9
     * @dev Contract module which provides a basic access control mechanism, where
    10
     * there is an account (an owner) that can be granted exclusive access to
    11
     * specific functions.
    12
     *
    13
     * The initial owner is set to the address provided by the deployer. This can
    14
     * later be changed with {transferOwnership}.
    15
     *
    16
     * This module is used through inheritance. It will make available the modifier
    17
     * `onlyOwner`, which can be applied to your functions to restrict their use to
    18
     * the owner.
    19
     */
    20
    abstract contract Ownable is Context {
    21
      address private _owner;
    22
    23
      /**
    24
       * @dev The caller account is not authorized to perform an operation.
    25
       */
    26
      error OwnableUnauthorizedAccount(address account);
    27
    28
      /**
    29
       * @dev The owner is not a valid owner account. (eg. `address(0)`)
    30
       */
    31
      error OwnableInvalidOwner(address owner);
    32
    33
      event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    34
    35
      /**
    36
       * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
    37
       */
    38
      constructor(address initialOwner) {
    39
        if (initialOwner == address(0)) {
    40
          revert OwnableInvalidOwner(address(0));
    41
        }
    42
        _transferOwnership(initialOwner);
    43
      }
    44
    45
      /**
    46
       * @dev Throws if called by any account other than the owner.
    47
       */
    48
      modifier onlyOwner() {
    49
        _checkOwner();
    50
        _;
    51
      }
    52
    53
      /**
    54
       * @dev Returns the address of the current owner.
    55
       */
    56
      function owner() public view virtual returns (address) {
    57
        return _owner;
    58
      }
    59
    60
      /**
    61
       * @dev Throws if the sender is not the owner.
    62
       */
    63
      function _checkOwner() internal view virtual {
    64
        if (owner() != _msgSender()) {
    65
          revert OwnableUnauthorizedAccount(_msgSender());
    66
        }
    67
      }
    68
    69
      /**
    70
       * @dev Leaves the contract without owner. It will not be possible to call
    71
       * `onlyOwner` functions. Can only be called by the current owner.
    72
       *
    73
       * NOTE: Renouncing ownership will leave the contract without an owner,
    74
       * thereby disabling any functionality that is only available to the owner.
    75
       */
    76
      function renounceOwnership() public virtual onlyOwner {
    77
        _transferOwnership(address(0));
    78
      }
    79
    80
      /**
    81
       * @dev Transfers ownership of the contract to a new account (`newOwner`).
    82
       * Can only be called by the current owner.
    83
       */
    84
      function transferOwnership(address newOwner) public virtual onlyOwner {
    85
        if (newOwner == address(0)) {
    86
          revert OwnableInvalidOwner(address(0));
    87
        }
    88
        _transferOwnership(newOwner);
    89
      }
    90
    91
      /**
    92
       * @dev Transfers ownership of the contract to a new account (`newOwner`).
    93
       * Internal function without access restriction.
    94
       */
    95
      function _transferOwnership(address newOwner) internal virtual {
    96
        address oldOwner = _owner;
    97
        _owner = newOwner;
    98
        emit OwnershipTransferred(oldOwner, newOwner);
    99
      }
    100
    }
    101
    100.0% src/dependencies/openzeppelin/Ownable2Step.sol
    Lines covered: 2 / 2 (100.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.1.0) (access/Ownable2Step.sol)
    3
    4
    pragma solidity ^0.8.20;
    5
    6
    import {Ownable} from './Ownable.sol';
    7
    8
    /**
    9
     * @dev Contract module which provides access control mechanism, where
    10
     * there is an account (an owner) that can be granted exclusive access to
    11
     * specific functions.
    12
     *
    13
     * This extension of the {Ownable} contract includes a two-step mechanism to transfer
    14
     * ownership, where the new owner must call {acceptOwnership} in order to replace the
    15
     * old one. This can help prevent common mistakes, such as transfers of ownership to
    16
     * incorrect accounts, or to contracts that are unable to interact with the
    17
     * permission system.
    18
     *
    19
     * The initial owner is specified at deployment time in the constructor for `Ownable`. This
    20
     * can later be changed with {transferOwnership} and {acceptOwnership}.
    21
     *
    22
     * This module is used through inheritance. It will make available all functions
    23
     * from parent (Ownable).
    24
     */
    25
    abstract contract Ownable2Step is Ownable {
    26
      address private _pendingOwner;
    27
    28
      event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
    29
    30
      /**
    31
       * @dev Returns the address of the pending owner.
    32
       */
    33
      function pendingOwner() public view virtual returns (address) {
    34
        return _pendingOwner;
    35
      }
    36
    37
      /**
    38
       * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
    39
       * Can only be called by the current owner.
    40
       *
    41
       * Setting `newOwner` to the zero address is allowed; this can be used to cancel an initiated ownership transfer.
    42
       */
    43
      function transferOwnership(address newOwner) public virtual override onlyOwner {
    44
        _pendingOwner = newOwner;
    45
        emit OwnershipTransferStarted(owner(), newOwner);
    46
      }
    47
    48
      /**
    49
       * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
    50
       * Internal function without access restriction.
    51
       */
    52
      function _transferOwnership(address newOwner) internal virtual override {
    53
        delete _pendingOwner;
    54
        super._transferOwnership(newOwner);
    55
      }
    56
    57
      /**
    58
       * @dev The new owner accepts the ownership transfer.
    59
       */
    60
      function acceptOwnership() public virtual {
    61
        address sender = _msgSender();
    62
        if (pendingOwner() != sender) {
    63
          revert OwnableUnauthorizedAccount(sender);
    64
        }
    65
        _transferOwnership(sender);
    66
      }
    67
    }
    68
    0.0% src/dependencies/openzeppelin/Panic.sol
    Lines covered: 0 / 9 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol)
    3
    4
    pragma solidity ^0.8.20;
    5
    6
    /**
    7
     * @dev Helper library for emitting standardized panic codes.
    8
     *
    9
     * ```solidity
    10
     * contract Example {
    11
     *      using Panic for uint256;
    12
     *
    13
     *      // Use any of the declared internal constants
    14
     *      function foo() { Panic.GENERIC.panic(); }
    15
     *
    16
     *      // Alternatively
    17
     *      function foo() { Panic.panic(Panic.GENERIC); }
    18
     * }
    19
     * ```
    20
     *
    21
     * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil].
    22
     *
    23
     * _Available since v5.1._
    24
     */
    25
    // slither-disable-next-line unused-state
    26
    library Panic {
    27
      /// @dev generic / unspecified error
    28
      uint256 internal constant GENERIC = 0x00;
    29
      /// @dev used by the assert() builtin
    30
      uint256 internal constant ASSERT = 0x01;
    31
      /// @dev arithmetic underflow or overflow
    32
      uint256 internal constant UNDER_OVERFLOW = 0x11;
    33
      /// @dev division or modulo by zero
    34
      uint256 internal constant DIVISION_BY_ZERO = 0x12;
    35
      /// @dev enum conversion error
    36
      uint256 internal constant ENUM_CONVERSION_ERROR = 0x21;
    37
      /// @dev invalid encoding in storage
    38
      uint256 internal constant STORAGE_ENCODING_ERROR = 0x22;
    39
      /// @dev empty array pop
    40
      uint256 internal constant EMPTY_ARRAY_POP = 0x31;
    41
      /// @dev array out of bounds access
    42
      uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32;
    43
      /// @dev resource error (too large allocation or too large array)
    44
      uint256 internal constant RESOURCE_ERROR = 0x41;
    45
      /// @dev calling invalid internal function
    46
      uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51;
    47
    48
      /// @dev Reverts with a panic code. Recommended to use with
    49
      /// the internal constants with predefined codes.
    50
      function panic(uint256 code) internal pure {
    51
        assembly ('memory-safe') {
    52
          mstore(0x00, 0x4e487b71)
    53
          mstore(0x20, code)
    54
          revert(0x1c, 0x24)
    55
        }
    56
      }
    57
    }
    58
    17.0% src/dependencies/openzeppelin/Proxy.sol
    Lines covered: 3 / 17 (17.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.0.0) (proxy/Proxy.sol)
    3
    4
    pragma solidity ^0.8.20;
    5
    6
    /**
    7
     * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
    8
     * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to
    9
     * be specified by overriding the virtual {_implementation} function.
    10
     *
    11
     * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
    12
     * different contract through the {_delegate} function.
    13
     *
    14
     * The success and return data of the delegated call will be returned back to the caller of the proxy.
    15
     */
    16
    abstract contract Proxy {
    17
        /**
    18
         * @dev Delegates the current call to `implementation`.
    19
         *
    20
         * This function does not return to its internal call site, it will return directly to the external caller.
    21
         */
    22
        function _delegate(address implementation) internal virtual {
    23
            assembly {
    24
                // Copy msg.data. We take full control of memory in this inline assembly
    25
                // block because it will not return to Solidity code. We overwrite the
    26
                // Solidity scratch pad at memory position 0.
    27
                calldatacopy(0, 0, calldatasize())
    28
    29
                // Call the implementation.
    30
                // out and outsize are 0 because we don't know the size yet.
    31
                let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
    32
    33
                // Copy the returned data.
    34
                returndatacopy(0, 0, returndatasize())
    35
    36
                switch result
    37
                // delegatecall returns 0 on error.
    38
                case 0 {
    39
                    revert(0, returndatasize())
    40
                }
    41
                default {
    42
                    return(0, returndatasize())
    43
                }
    44
            }
    45
        }
    46
    47
        /**
    48
         * @dev This is a virtual function that should be overridden so it returns the address to which the fallback
    49
         * function and {_fallback} should delegate.
    50
         */
    51
        function _implementation() internal view virtual returns (address);
    52
    53
        /**
    54
         * @dev Delegates the current call to the address returned by `_implementation()`.
    55
         *
    56
         * This function does not return to its internal call site, it will return directly to the external caller.
    57
         */
    58
        function _fallback() internal virtual {
    59
            _delegate(_implementation());
    60
        }
    61
    62
        /**
    63
         * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
    64
         * function in the contract matches the call data.
    65
         */
    66
        fallback() external payable virtual {
    67
            _fallback();
    68
        }
    69
    }
    70
    14.0% src/dependencies/openzeppelin/ProxyAdmin.sol
    Lines covered: 1 / 7 (14.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.2.0) (proxy/transparent/ProxyAdmin.sol)
    3
    4
    pragma solidity ^0.8.22;
    5
    6
    import {ITransparentUpgradeableProxy} from './TransparentUpgradeableProxy.sol';
    7
    import {Ownable} from './Ownable.sol';
    8
    9
    /**
    10
     * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an
    11
     * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.
    12
     */
    13
    contract ProxyAdmin is Ownable {
    14
      /**
    15
       * @dev The version of the upgrade interface of the contract. If this getter is missing, both `upgrade(address,address)`
    16
       * and `upgradeAndCall(address,address,bytes)` are present, and `upgrade` must be used if no function should be called,
    17
       * while `upgradeAndCall` will invoke the `receive` function if the third argument is the empty byte string.
    18
       * If the getter returns `"5.0.0"`, only `upgradeAndCall(address,address,bytes)` is present, and the third argument must
    19
       * be the empty byte string if no function should be called, making it impossible to invoke the `receive` function
    20
       * during an upgrade.
    21
       */
    22
      string public constant UPGRADE_INTERFACE_VERSION = '5.0.0';
    23
    24
      /**
    25
       * @dev Sets the initial owner who can perform upgrades.
    26
       */
    27
      constructor(address initialOwner) Ownable(initialOwner) {}
    28
    29
      /**
    30
       * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation.
    31
       * See {TransparentUpgradeableProxy-_dispatchUpgradeToAndCall}.
    32
       *
    33
       * Requirements:
    34
       *
    35
       * - This contract must be the admin of `proxy`.
    36
       * - If `data` is empty, `msg.value` must be zero.
    37
       */
    38
      function upgradeAndCall(
    39
        ITransparentUpgradeableProxy proxy,
    40
        address implementation,
    41
        bytes memory data
    42
      ) public payable virtual onlyOwner {
    43
        proxy.upgradeToAndCall{value: msg.value}(implementation, data);
    44
      }
    45
    }
    46
    100.0% src/dependencies/openzeppelin/ReentrancyGuardTransient.sol
    Lines covered: 1 / 1 (100.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.3.0) (utils/ReentrancyGuardTransient.sol)
    3
    4
    pragma solidity ^0.8.24;
    5
    6
    import {TransientSlot} from './TransientSlot.sol';
    7
    8
    /**
    9
     * @dev Variant of {ReentrancyGuard} that uses transient storage.
    10
     *
    11
     * NOTE: This variant only works on networks where EIP-1153 is available.
    12
     *
    13
     * _Available since v5.1._
    14
     */
    15
    abstract contract ReentrancyGuardTransient {
    16
      using TransientSlot for *;
    17
    18
      // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ReentrancyGuard")) - 1)) & ~bytes32(uint256(0xff))
    19
      bytes32 private constant REENTRANCY_GUARD_STORAGE =
    20
        0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00;
    21
    22
      /**
    23
       * @dev Unauthorized reentrant call.
    24
       */
    25
      error ReentrancyGuardReentrantCall();
    26
    27
      /**
    28
       * @dev Prevents a contract from calling itself, directly or indirectly.
    29
       * Calling a `nonReentrant` function from another `nonReentrant`
    30
       * function is not supported. It is possible to prevent this from happening
    31
       * by making the `nonReentrant` function external, and making it call a
    32
       * `private` function that does the actual work.
    33
       */
    34
      modifier nonReentrant() {
    35
        _nonReentrantBefore();
    36
        _;
    37
        _nonReentrantAfter();
    38
      }
    39
    40
      function _nonReentrantBefore() private {
    41
        // On the first call to nonReentrant, REENTRANCY_GUARD_STORAGE.asBoolean().tload() will be false
    42
        if (_reentrancyGuardEntered()) {
    43
          revert ReentrancyGuardReentrantCall();
    44
        }
    45
    46
        // Any calls to nonReentrant after this point will fail
    47
        REENTRANCY_GUARD_STORAGE.asBoolean().tstore(true);
    48
      }
    49
    50
      function _nonReentrantAfter() private {
    51
        REENTRANCY_GUARD_STORAGE.asBoolean().tstore(false);
    52
      }
    53
    54
      /**
    55
       * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
    56
       * `nonReentrant` function in the call stack.
    57
       */
    58
      function _reentrancyGuardEntered() internal view returns (bool) {
    59
        return REENTRANCY_GUARD_STORAGE.asBoolean().tload();
    60
      }
    61
    }
    62
    0.0% src/dependencies/openzeppelin/SafeCast.sol
    Lines covered: 0 / 12 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol)
    3
    // This file was procedurally generated from scripts/generate/templates/SafeCast.js.
    4
    5
    pragma solidity ^0.8.20;
    6
    7
    /**
    8
     * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow
    9
     * checks.
    10
     *
    11
     * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
    12
     * easily result in undesired exploitation or bugs, since developers usually
    13
     * assume that overflows raise errors. `SafeCast` restores this intuition by
    14
     * reverting the transaction when such an operation overflows.
    15
     *
    16
     * Using this library instead of the unchecked operations eliminates an entire
    17
     * class of bugs, so it's recommended to use it always.
    18
     */
    19
    library SafeCast {
    20
      /**
    21
       * @dev Value doesn't fit in an uint of `bits` size.
    22
       */
    23
      error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);
    24
    25
      /**
    26
       * @dev An int value doesn't fit in an uint of `bits` size.
    27
       */
    28
      error SafeCastOverflowedIntToUint(int256 value);
    29
    30
      /**
    31
       * @dev Value doesn't fit in an int of `bits` size.
    32
       */
    33
      error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);
    34
    35
      /**
    36
       * @dev An uint value doesn't fit in an int of `bits` size.
    37
       */
    38
      error SafeCastOverflowedUintToInt(uint256 value);
    39
    40
      /**
    41
       * @dev Returns the downcasted uint248 from uint256, reverting on
    42
       * overflow (when the input is greater than largest uint248).
    43
       *
    44
       * Counterpart to Solidity's `uint248` operator.
    45
       *
    46
       * Requirements:
    47
       *
    48
       * - input must fit into 248 bits
    49
       */
    50
      function toUint248(uint256 value) internal pure returns (uint248) {
    51
        if (value > type(uint248).max) {
    52
          revert SafeCastOverflowedUintDowncast(248, value);
    53
        }
    54
        return uint248(value);
    55
      }
    56
    57
      /**
    58
       * @dev Returns the downcasted uint240 from uint256, reverting on
    59
       * overflow (when the input is greater than largest uint240).
    60
       *
    61
       * Counterpart to Solidity's `uint240` operator.
    62
       *
    63
       * Requirements:
    64
       *
    65
       * - input must fit into 240 bits
    66
       */
    67
      function toUint240(uint256 value) internal pure returns (uint240) {
    68
        if (value > type(uint240).max) {
    69
          revert SafeCastOverflowedUintDowncast(240, value);
    70
        }
    71
        return uint240(value);
    72
      }
    73
    74
      /**
    75
       * @dev Returns the downcasted uint232 from uint256, reverting on
    76
       * overflow (when the input is greater than largest uint232).
    77
       *
    78
       * Counterpart to Solidity's `uint232` operator.
    79
       *
    80
       * Requirements:
    81
       *
    82
       * - input must fit into 232 bits
    83
       */
    84
      function toUint232(uint256 value) internal pure returns (uint232) {
    85
        if (value > type(uint232).max) {
    86
          revert SafeCastOverflowedUintDowncast(232, value);
    87
        }
    88
        return uint232(value);
    89
      }
    90
    91
      /**
    92
       * @dev Returns the downcasted uint224 from uint256, reverting on
    93
       * overflow (when the input is greater than largest uint224).
    94
       *
    95
       * Counterpart to Solidity's `uint224` operator.
    96
       *
    97
       * Requirements:
    98
       *
    99
       * - input must fit into 224 bits
    100
       */
    101
      function toUint224(uint256 value) internal pure returns (uint224) {
    102
        if (value > type(uint224).max) {
    103
          revert SafeCastOverflowedUintDowncast(224, value);
    104
        }
    105
        return uint224(value);
    106
      }
    107
    108
      /**
    109
       * @dev Returns the downcasted uint216 from uint256, reverting on
    110
       * overflow (when the input is greater than largest uint216).
    111
       *
    112
       * Counterpart to Solidity's `uint216` operator.
    113
       *
    114
       * Requirements:
    115
       *
    116
       * - input must fit into 216 bits
    117
       */
    118
      function toUint216(uint256 value) internal pure returns (uint216) {
    119
        if (value > type(uint216).max) {
    120
          revert SafeCastOverflowedUintDowncast(216, value);
    121
        }
    122
        return uint216(value);
    123
      }
    124
    125
      /**
    126
       * @dev Returns the downcasted uint208 from uint256, reverting on
    127
       * overflow (when the input is greater than largest uint208).
    128
       *
    129
       * Counterpart to Solidity's `uint208` operator.
    130
       *
    131
       * Requirements:
    132
       *
    133
       * - input must fit into 208 bits
    134
       */
    135
      function toUint208(uint256 value) internal pure returns (uint208) {
    136
        if (value > type(uint208).max) {
    137
          revert SafeCastOverflowedUintDowncast(208, value);
    138
        }
    139
        return uint208(value);
    140
      }
    141
    142
      /**
    143
       * @dev Returns the downcasted uint200 from uint256, reverting on
    144
       * overflow (when the input is greater than largest uint200).
    145
       *
    146
       * Counterpart to Solidity's `uint200` operator.
    147
       *
    148
       * Requirements:
    149
       *
    150
       * - input must fit into 200 bits
    151
       */
    152
      function toUint200(uint256 value) internal pure returns (uint200) {
    153
        if (value > type(uint200).max) {
    154
          revert SafeCastOverflowedUintDowncast(200, value);
    155
        }
    156
        return uint200(value);
    157
      }
    158
    159
      /**
    160
       * @dev Returns the downcasted uint192 from uint256, reverting on
    161
       * overflow (when the input is greater than largest uint192).
    162
       *
    163
       * Counterpart to Solidity's `uint192` operator.
    164
       *
    165
       * Requirements:
    166
       *
    167
       * - input must fit into 192 bits
    168
       */
    169
      function toUint192(uint256 value) internal pure returns (uint192) {
    170
        if (value > type(uint192).max) {
    171
          revert SafeCastOverflowedUintDowncast(192, value);
    172
        }
    173
        return uint192(value);
    174
      }
    175
    176
      /**
    177
       * @dev Returns the downcasted uint184 from uint256, reverting on
    178
       * overflow (when the input is greater than largest uint184).
    179
       *
    180
       * Counterpart to Solidity's `uint184` operator.
    181
       *
    182
       * Requirements:
    183
       *
    184
       * - input must fit into 184 bits
    185
       */
    186
      function toUint184(uint256 value) internal pure returns (uint184) {
    187
        if (value > type(uint184).max) {
    188
          revert SafeCastOverflowedUintDowncast(184, value);
    189
        }
    190
        return uint184(value);
    191
      }
    192
    193
      /**
    194
       * @dev Returns the downcasted uint176 from uint256, reverting on
    195
       * overflow (when the input is greater than largest uint176).
    196
       *
    197
       * Counterpart to Solidity's `uint176` operator.
    198
       *
    199
       * Requirements:
    200
       *
    201
       * - input must fit into 176 bits
    202
       */
    203
      function toUint176(uint256 value) internal pure returns (uint176) {
    204
        if (value > type(uint176).max) {
    205
          revert SafeCastOverflowedUintDowncast(176, value);
    206
        }
    207
        return uint176(value);
    208
      }
    209
    210
      /**
    211
       * @dev Returns the downcasted uint168 from uint256, reverting on
    212
       * overflow (when the input is greater than largest uint168).
    213
       *
    214
       * Counterpart to Solidity's `uint168` operator.
    215
       *
    216
       * Requirements:
    217
       *
    218
       * - input must fit into 168 bits
    219
       */
    220
      function toUint168(uint256 value) internal pure returns (uint168) {
    221
        if (value > type(uint168).max) {
    222
          revert SafeCastOverflowedUintDowncast(168, value);
    223
        }
    224
        return uint168(value);
    225
      }
    226
    227
      /**
    228
       * @dev Returns the downcasted uint160 from uint256, reverting on
    229
       * overflow (when the input is greater than largest uint160).
    230
       *
    231
       * Counterpart to Solidity's `uint160` operator.
    232
       *
    233
       * Requirements:
    234
       *
    235
       * - input must fit into 160 bits
    236
       */
    237
      function toUint160(uint256 value) internal pure returns (uint160) {
    238
        if (value > type(uint160).max) {
    239
          revert SafeCastOverflowedUintDowncast(160, value);
    240
        }
    241
        return uint160(value);
    242
      }
    243
    244
      /**
    245
       * @dev Returns the downcasted uint152 from uint256, reverting on
    246
       * overflow (when the input is greater than largest uint152).
    247
       *
    248
       * Counterpart to Solidity's `uint152` operator.
    249
       *
    250
       * Requirements:
    251
       *
    252
       * - input must fit into 152 bits
    253
       */
    254
      function toUint152(uint256 value) internal pure returns (uint152) {
    255
        if (value > type(uint152).max) {
    256
          revert SafeCastOverflowedUintDowncast(152, value);
    257
        }
    258
        return uint152(value);
    259
      }
    260
    261
      /**
    262
       * @dev Returns the downcasted uint144 from uint256, reverting on
    263
       * overflow (when the input is greater than largest uint144).
    264
       *
    265
       * Counterpart to Solidity's `uint144` operator.
    266
       *
    267
       * Requirements:
    268
       *
    269
       * - input must fit into 144 bits
    270
       */
    271
      function toUint144(uint256 value) internal pure returns (uint144) {
    272
        if (value > type(uint144).max) {
    273
          revert SafeCastOverflowedUintDowncast(144, value);
    274
        }
    275
        return uint144(value);
    276
      }
    277
    278
      /**
    279
       * @dev Returns the downcasted uint136 from uint256, reverting on
    280
       * overflow (when the input is greater than largest uint136).
    281
       *
    282
       * Counterpart to Solidity's `uint136` operator.
    283
       *
    284
       * Requirements:
    285
       *
    286
       * - input must fit into 136 bits
    287
       */
    288
      function toUint136(uint256 value) internal pure returns (uint136) {
    289
        if (value > type(uint136).max) {
    290
          revert SafeCastOverflowedUintDowncast(136, value);
    291
        }
    292
        return uint136(value);
    293
      }
    294
    295
      /**
    296
       * @dev Returns the downcasted uint128 from uint256, reverting on
    297
       * overflow (when the input is greater than largest uint128).
    298
       *
    299
       * Counterpart to Solidity's `uint128` operator.
    300
       *
    301
       * Requirements:
    302
       *
    303
       * - input must fit into 128 bits
    304
       */
    305
      function toUint128(uint256 value) internal pure returns (uint128) {
    306
        if (value > type(uint128).max) {
    307
          revert SafeCastOverflowedUintDowncast(128, value);
    308
        }
    309
        return uint128(value);
    310
      }
    311
    312
      /**
    313
       * @dev Returns the downcasted uint120 from uint256, reverting on
    314
       * overflow (when the input is greater than largest uint120).
    315
       *
    316
       * Counterpart to Solidity's `uint120` operator.
    317
       *
    318
       * Requirements:
    319
       *
    320
       * - input must fit into 120 bits
    321
       */
    322
      function toUint120(uint256 value) internal pure returns (uint120) {
    323
        if (value > type(uint120).max) {
    324
          revert SafeCastOverflowedUintDowncast(120, value);
    325
        }
    326
        return uint120(value);
    327
      }
    328
    329
      /**
    330
       * @dev Returns the downcasted uint112 from uint256, reverting on
    331
       * overflow (when the input is greater than largest uint112).
    332
       *
    333
       * Counterpart to Solidity's `uint112` operator.
    334
       *
    335
       * Requirements:
    336
       *
    337
       * - input must fit into 112 bits
    338
       */
    339
      function toUint112(uint256 value) internal pure returns (uint112) {
    340
        if (value > type(uint112).max) {
    341
          revert SafeCastOverflowedUintDowncast(112, value);
    342
        }
    343
        return uint112(value);
    344
      }
    345
    346
      /**
    347
       * @dev Returns the downcasted uint104 from uint256, reverting on
    348
       * overflow (when the input is greater than largest uint104).
    349
       *
    350
       * Counterpart to Solidity's `uint104` operator.
    351
       *
    352
       * Requirements:
    353
       *
    354
       * - input must fit into 104 bits
    355
       */
    356
      function toUint104(uint256 value) internal pure returns (uint104) {
    357
        if (value > type(uint104).max) {
    358
          revert SafeCastOverflowedUintDowncast(104, value);
    359
        }
    360
        return uint104(value);
    361
      }
    362
    363
      /**
    364
       * @dev Returns the downcasted uint96 from uint256, reverting on
    365
       * overflow (when the input is greater than largest uint96).
    366
       *
    367
       * Counterpart to Solidity's `uint96` operator.
    368
       *
    369
       * Requirements:
    370
       *
    371
       * - input must fit into 96 bits
    372
       */
    373
      function toUint96(uint256 value) internal pure returns (uint96) {
    374
        if (value > type(uint96).max) {
    375
          revert SafeCastOverflowedUintDowncast(96, value);
    376
        }
    377
        return uint96(value);
    378
      }
    379
    380
      /**
    381
       * @dev Returns the downcasted uint88 from uint256, reverting on
    382
       * overflow (when the input is greater than largest uint88).
    383
       *
    384
       * Counterpart to Solidity's `uint88` operator.
    385
       *
    386
       * Requirements:
    387
       *
    388
       * - input must fit into 88 bits
    389
       */
    390
      function toUint88(uint256 value) internal pure returns (uint88) {
    391
        if (value > type(uint88).max) {
    392
          revert SafeCastOverflowedUintDowncast(88, value);
    393
        }
    394
        return uint88(value);
    395
      }
    396
    397
      /**
    398
       * @dev Returns the downcasted uint80 from uint256, reverting on
    399
       * overflow (when the input is greater than largest uint80).
    400
       *
    401
       * Counterpart to Solidity's `uint80` operator.
    402
       *
    403
       * Requirements:
    404
       *
    405
       * - input must fit into 80 bits
    406
       */
    407
      function toUint80(uint256 value) internal pure returns (uint80) {
    408
        if (value > type(uint80).max) {
    409
          revert SafeCastOverflowedUintDowncast(80, value);
    410
        }
    411
        return uint80(value);
    412
      }
    413
    414
      /**
    415
       * @dev Returns the downcasted uint72 from uint256, reverting on
    416
       * overflow (when the input is greater than largest uint72).
    417
       *
    418
       * Counterpart to Solidity's `uint72` operator.
    419
       *
    420
       * Requirements:
    421
       *
    422
       * - input must fit into 72 bits
    423
       */
    424
      function toUint72(uint256 value) internal pure returns (uint72) {
    425
        if (value > type(uint72).max) {
    426
          revert SafeCastOverflowedUintDowncast(72, value);
    427
        }
    428
        return uint72(value);
    429
      }
    430
    431
      /**
    432
       * @dev Returns the downcasted uint64 from uint256, reverting on
    433
       * overflow (when the input is greater than largest uint64).
    434
       *
    435
       * Counterpart to Solidity's `uint64` operator.
    436
       *
    437
       * Requirements:
    438
       *
    439
       * - input must fit into 64 bits
    440
       */
    441
      function toUint64(uint256 value) internal pure returns (uint64) {
    442
        if (value > type(uint64).max) {
    443
          revert SafeCastOverflowedUintDowncast(64, value);
    444
        }
    445
        return uint64(value);
    446
      }
    447
    448
      /**
    449
       * @dev Returns the downcasted uint56 from uint256, reverting on
    450
       * overflow (when the input is greater than largest uint56).
    451
       *
    452
       * Counterpart to Solidity's `uint56` operator.
    453
       *
    454
       * Requirements:
    455
       *
    456
       * - input must fit into 56 bits
    457
       */
    458
      function toUint56(uint256 value) internal pure returns (uint56) {
    459
        if (value > type(uint56).max) {
    460
          revert SafeCastOverflowedUintDowncast(56, value);
    461
        }
    462
        return uint56(value);
    463
      }
    464
    465
      /**
    466
       * @dev Returns the downcasted uint48 from uint256, reverting on
    467
       * overflow (when the input is greater than largest uint48).
    468
       *
    469
       * Counterpart to Solidity's `uint48` operator.
    470
       *
    471
       * Requirements:
    472
       *
    473
       * - input must fit into 48 bits
    474
       */
    475
      function toUint48(uint256 value) internal pure returns (uint48) {
    476
        if (value > type(uint48).max) {
    477
          revert SafeCastOverflowedUintDowncast(48, value);
    478
        }
    479
        return uint48(value);
    480
      }
    481
    482
      /**
    483
       * @dev Returns the downcasted uint40 from uint256, reverting on
    484
       * overflow (when the input is greater than largest uint40).
    485
       *
    486
       * Counterpart to Solidity's `uint40` operator.
    487
       *
    488
       * Requirements:
    489
       *
    490
       * - input must fit into 40 bits
    491
       */
    492
      function toUint40(uint256 value) internal pure returns (uint40) {
    493
        if (value > type(uint40).max) {
    494
          revert SafeCastOverflowedUintDowncast(40, value);
    495
        }
    496
        return uint40(value);
    497
      }
    498
    499
      /**
    500
       * @dev Returns the downcasted uint32 from uint256, reverting on
    501
       * overflow (when the input is greater than largest uint32).
    502
       *
    503
       * Counterpart to Solidity's `uint32` operator.
    504
       *
    505
       * Requirements:
    506
       *
    507
       * - input must fit into 32 bits
    508
       */
    509
      function toUint32(uint256 value) internal pure returns (uint32) {
    510
        if (value > type(uint32).max) {
    511
          revert SafeCastOverflowedUintDowncast(32, value);
    512
        }
    513
        return uint32(value);
    514
      }
    515
    516
      /**
    517
       * @dev Returns the downcasted uint24 from uint256, reverting on
    518
       * overflow (when the input is greater than largest uint24).
    519
       *
    520
       * Counterpart to Solidity's `uint24` operator.
    521
       *
    522
       * Requirements:
    523
       *
    524
       * - input must fit into 24 bits
    525
       */
    526
      function toUint24(uint256 value) internal pure returns (uint24) {
    527
        if (value > type(uint24).max) {
    528
          revert SafeCastOverflowedUintDowncast(24, value);
    529
        }
    530
        return uint24(value);
    531
      }
    532
    533
      /**
    534
       * @dev Returns the downcasted uint16 from uint256, reverting on
    535
       * overflow (when the input is greater than largest uint16).
    536
       *
    537
       * Counterpart to Solidity's `uint16` operator.
    538
       *
    539
       * Requirements:
    540
       *
    541
       * - input must fit into 16 bits
    542
       */
    543
      function toUint16(uint256 value) internal pure returns (uint16) {
    544
        if (value > type(uint16).max) {
    545
          revert SafeCastOverflowedUintDowncast(16, value);
    546
        }
    547
        return uint16(value);
    548
      }
    549
    550
      /**
    551
       * @dev Returns the downcasted uint8 from uint256, reverting on
    552
       * overflow (when the input is greater than largest uint8).
    553
       *
    554
       * Counterpart to Solidity's `uint8` operator.
    555
       *
    556
       * Requirements:
    557
       *
    558
       * - input must fit into 8 bits
    559
       */
    560
      function toUint8(uint256 value) internal pure returns (uint8) {
    561
        if (value > type(uint8).max) {
    562
          revert SafeCastOverflowedUintDowncast(8, value);
    563
        }
    564
        return uint8(value);
    565
      }
    566
    567
      /**
    568
       * @dev Converts a signed int256 into an unsigned uint256.
    569
       *
    570
       * Requirements:
    571
       *
    572
       * - input must be greater than or equal to 0.
    573
       */
    574
      function toUint256(int256 value) internal pure returns (uint256) {
    575
        if (value < 0) {
    576
          revert SafeCastOverflowedIntToUint(value);
    577
        }
    578
        return uint256(value);
    579
      }
    580
    581
      /**
    582
       * @dev Returns the downcasted int248 from int256, reverting on
    583
       * overflow (when the input is less than smallest int248 or
    584
       * greater than largest int248).
    585
       *
    586
       * Counterpart to Solidity's `int248` operator.
    587
       *
    588
       * Requirements:
    589
       *
    590
       * - input must fit into 248 bits
    591
       */
    592
      function toInt248(int256 value) internal pure returns (int248 downcasted) {
    593
        downcasted = int248(value);
    594
        if (downcasted != value) {
    595
          revert SafeCastOverflowedIntDowncast(248, value);
    596
        }
    597
      }
    598
    599
      /**
    600
       * @dev Returns the downcasted int240 from int256, reverting on
    601
       * overflow (when the input is less than smallest int240 or
    602
       * greater than largest int240).
    603
       *
    604
       * Counterpart to Solidity's `int240` operator.
    605
       *
    606
       * Requirements:
    607
       *
    608
       * - input must fit into 240 bits
    609
       */
    610
      function toInt240(int256 value) internal pure returns (int240 downcasted) {
    611
        downcasted = int240(value);
    612
        if (downcasted != value) {
    613
          revert SafeCastOverflowedIntDowncast(240, value);
    614
        }
    615
      }
    616
    617
      /**
    618
       * @dev Returns the downcasted int232 from int256, reverting on
    619
       * overflow (when the input is less than smallest int232 or
    620
       * greater than largest int232).
    621
       *
    622
       * Counterpart to Solidity's `int232` operator.
    623
       *
    624
       * Requirements:
    625
       *
    626
       * - input must fit into 232 bits
    627
       */
    628
      function toInt232(int256 value) internal pure returns (int232 downcasted) {
    629
        downcasted = int232(value);
    630
        if (downcasted != value) {
    631
          revert SafeCastOverflowedIntDowncast(232, value);
    632
        }
    633
      }
    634
    635
      /**
    636
       * @dev Returns the downcasted int224 from int256, reverting on
    637
       * overflow (when the input is less than smallest int224 or
    638
       * greater than largest int224).
    639
       *
    640
       * Counterpart to Solidity's `int224` operator.
    641
       *
    642
       * Requirements:
    643
       *
    644
       * - input must fit into 224 bits
    645
       */
    646
      function toInt224(int256 value) internal pure returns (int224 downcasted) {
    647
        downcasted = int224(value);
    648
        if (downcasted != value) {
    649
          revert SafeCastOverflowedIntDowncast(224, value);
    650
        }
    651
      }
    652
    653
      /**
    654
       * @dev Returns the downcasted int216 from int256, reverting on
    655
       * overflow (when the input is less than smallest int216 or
    656
       * greater than largest int216).
    657
       *
    658
       * Counterpart to Solidity's `int216` operator.
    659
       *
    660
       * Requirements:
    661
       *
    662
       * - input must fit into 216 bits
    663
       */
    664
      function toInt216(int256 value) internal pure returns (int216 downcasted) {
    665
        downcasted = int216(value);
    666
        if (downcasted != value) {
    667
          revert SafeCastOverflowedIntDowncast(216, value);
    668
        }
    669
      }
    670
    671
      /**
    672
       * @dev Returns the downcasted int208 from int256, reverting on
    673
       * overflow (when the input is less than smallest int208 or
    674
       * greater than largest int208).
    675
       *
    676
       * Counterpart to Solidity's `int208` operator.
    677
       *
    678
       * Requirements:
    679
       *
    680
       * - input must fit into 208 bits
    681
       */
    682
      function toInt208(int256 value) internal pure returns (int208 downcasted) {
    683
        downcasted = int208(value);
    684
        if (downcasted != value) {
    685
          revert SafeCastOverflowedIntDowncast(208, value);
    686
        }
    687
      }
    688
    689
      /**
    690
       * @dev Returns the downcasted int200 from int256, reverting on
    691
       * overflow (when the input is less than smallest int200 or
    692
       * greater than largest int200).
    693
       *
    694
       * Counterpart to Solidity's `int200` operator.
    695
       *
    696
       * Requirements:
    697
       *
    698
       * - input must fit into 200 bits
    699
       */
    700
      function toInt200(int256 value) internal pure returns (int200 downcasted) {
    701
        downcasted = int200(value);
    702
        if (downcasted != value) {
    703
          revert SafeCastOverflowedIntDowncast(200, value);
    704
        }
    705
      }
    706
    707
      /**
    708
       * @dev Returns the downcasted int192 from int256, reverting on
    709
       * overflow (when the input is less than smallest int192 or
    710
       * greater than largest int192).
    711
       *
    712
       * Counterpart to Solidity's `int192` operator.
    713
       *
    714
       * Requirements:
    715
       *
    716
       * - input must fit into 192 bits
    717
       */
    718
      function toInt192(int256 value) internal pure returns (int192 downcasted) {
    719
        downcasted = int192(value);
    720
        if (downcasted != value) {
    721
          revert SafeCastOverflowedIntDowncast(192, value);
    722
        }
    723
      }
    724
    725
      /**
    726
       * @dev Returns the downcasted int184 from int256, reverting on
    727
       * overflow (when the input is less than smallest int184 or
    728
       * greater than largest int184).
    729
       *
    730
       * Counterpart to Solidity's `int184` operator.
    731
       *
    732
       * Requirements:
    733
       *
    734
       * - input must fit into 184 bits
    735
       */
    736
      function toInt184(int256 value) internal pure returns (int184 downcasted) {
    737
        downcasted = int184(value);
    738
        if (downcasted != value) {
    739
          revert SafeCastOverflowedIntDowncast(184, value);
    740
        }
    741
      }
    742
    743
      /**
    744
       * @dev Returns the downcasted int176 from int256, reverting on
    745
       * overflow (when the input is less than smallest int176 or
    746
       * greater than largest int176).
    747
       *
    748
       * Counterpart to Solidity's `int176` operator.
    749
       *
    750
       * Requirements:
    751
       *
    752
       * - input must fit into 176 bits
    753
       */
    754
      function toInt176(int256 value) internal pure returns (int176 downcasted) {
    755
        downcasted = int176(value);
    756
        if (downcasted != value) {
    757
          revert SafeCastOverflowedIntDowncast(176, value);
    758
        }
    759
      }
    760
    761
      /**
    762
       * @dev Returns the downcasted int168 from int256, reverting on
    763
       * overflow (when the input is less than smallest int168 or
    764
       * greater than largest int168).
    765
       *
    766
       * Counterpart to Solidity's `int168` operator.
    767
       *
    768
       * Requirements:
    769
       *
    770
       * - input must fit into 168 bits
    771
       */
    772
      function toInt168(int256 value) internal pure returns (int168 downcasted) {
    773
        downcasted = int168(value);
    774
        if (downcasted != value) {
    775
          revert SafeCastOverflowedIntDowncast(168, value);
    776
        }
    777
      }
    778
    779
      /**
    780
       * @dev Returns the downcasted int160 from int256, reverting on
    781
       * overflow (when the input is less than smallest int160 or
    782
       * greater than largest int160).
    783
       *
    784
       * Counterpart to Solidity's `int160` operator.
    785
       *
    786
       * Requirements:
    787
       *
    788
       * - input must fit into 160 bits
    789
       */
    790
      function toInt160(int256 value) internal pure returns (int160 downcasted) {
    791
        downcasted = int160(value);
    792
        if (downcasted != value) {
    793
          revert SafeCastOverflowedIntDowncast(160, value);
    794
        }
    795
      }
    796
    797
      /**
    798
       * @dev Returns the downcasted int152 from int256, reverting on
    799
       * overflow (when the input is less than smallest int152 or
    800
       * greater than largest int152).
    801
       *
    802
       * Counterpart to Solidity's `int152` operator.
    803
       *
    804
       * Requirements:
    805
       *
    806
       * - input must fit into 152 bits
    807
       */
    808
      function toInt152(int256 value) internal pure returns (int152 downcasted) {
    809
        downcasted = int152(value);
    810
        if (downcasted != value) {
    811
          revert SafeCastOverflowedIntDowncast(152, value);
    812
        }
    813
      }
    814
    815
      /**
    816
       * @dev Returns the downcasted int144 from int256, reverting on
    817
       * overflow (when the input is less than smallest int144 or
    818
       * greater than largest int144).
    819
       *
    820
       * Counterpart to Solidity's `int144` operator.
    821
       *
    822
       * Requirements:
    823
       *
    824
       * - input must fit into 144 bits
    825
       */
    826
      function toInt144(int256 value) internal pure returns (int144 downcasted) {
    827
        downcasted = int144(value);
    828
        if (downcasted != value) {
    829
          revert SafeCastOverflowedIntDowncast(144, value);
    830
        }
    831
      }
    832
    833
      /**
    834
       * @dev Returns the downcasted int136 from int256, reverting on
    835
       * overflow (when the input is less than smallest int136 or
    836
       * greater than largest int136).
    837
       *
    838
       * Counterpart to Solidity's `int136` operator.
    839
       *
    840
       * Requirements:
    841
       *
    842
       * - input must fit into 136 bits
    843
       */
    844
      function toInt136(int256 value) internal pure returns (int136 downcasted) {
    845
        downcasted = int136(value);
    846
        if (downcasted != value) {
    847
          revert SafeCastOverflowedIntDowncast(136, value);
    848
        }
    849
      }
    850
    851
      /**
    852
       * @dev Returns the downcasted int128 from int256, reverting on
    853
       * overflow (when the input is less than smallest int128 or
    854
       * greater than largest int128).
    855
       *
    856
       * Counterpart to Solidity's `int128` operator.
    857
       *
    858
       * Requirements:
    859
       *
    860
       * - input must fit into 128 bits
    861
       */
    862
      function toInt128(int256 value) internal pure returns (int128 downcasted) {
    863
        downcasted = int128(value);
    864
        if (downcasted != value) {
    865
          revert SafeCastOverflowedIntDowncast(128, value);
    866
        }
    867
      }
    868
    869
      /**
    870
       * @dev Returns the downcasted int120 from int256, reverting on
    871
       * overflow (when the input is less than smallest int120 or
    872
       * greater than largest int120).
    873
       *
    874
       * Counterpart to Solidity's `int120` operator.
    875
       *
    876
       * Requirements:
    877
       *
    878
       * - input must fit into 120 bits
    879
       */
    880
      function toInt120(int256 value) internal pure returns (int120 downcasted) {
    881
        downcasted = int120(value);
    882
        if (downcasted != value) {
    883
          revert SafeCastOverflowedIntDowncast(120, value);
    884
        }
    885
      }
    886
    887
      /**
    888
       * @dev Returns the downcasted int112 from int256, reverting on
    889
       * overflow (when the input is less than smallest int112 or
    890
       * greater than largest int112).
    891
       *
    892
       * Counterpart to Solidity's `int112` operator.
    893
       *
    894
       * Requirements:
    895
       *
    896
       * - input must fit into 112 bits
    897
       */
    898
      function toInt112(int256 value) internal pure returns (int112 downcasted) {
    899
        downcasted = int112(value);
    900
        if (downcasted != value) {
    901
          revert SafeCastOverflowedIntDowncast(112, value);
    902
        }
    903
      }
    904
    905
      /**
    906
       * @dev Returns the downcasted int104 from int256, reverting on
    907
       * overflow (when the input is less than smallest int104 or
    908
       * greater than largest int104).
    909
       *
    910
       * Counterpart to Solidity's `int104` operator.
    911
       *
    912
       * Requirements:
    913
       *
    914
       * - input must fit into 104 bits
    915
       */
    916
      function toInt104(int256 value) internal pure returns (int104 downcasted) {
    917
        downcasted = int104(value);
    918
        if (downcasted != value) {
    919
          revert SafeCastOverflowedIntDowncast(104, value);
    920
        }
    921
      }
    922
    923
      /**
    924
       * @dev Returns the downcasted int96 from int256, reverting on
    925
       * overflow (when the input is less than smallest int96 or
    926
       * greater than largest int96).
    927
       *
    928
       * Counterpart to Solidity's `int96` operator.
    929
       *
    930
       * Requirements:
    931
       *
    932
       * - input must fit into 96 bits
    933
       */
    934
      function toInt96(int256 value) internal pure returns (int96 downcasted) {
    935
        downcasted = int96(value);
    936
        if (downcasted != value) {
    937
          revert SafeCastOverflowedIntDowncast(96, value);
    938
        }
    939
      }
    940
    941
      /**
    942
       * @dev Returns the downcasted int88 from int256, reverting on
    943
       * overflow (when the input is less than smallest int88 or
    944
       * greater than largest int88).
    945
       *
    946
       * Counterpart to Solidity's `int88` operator.
    947
       *
    948
       * Requirements:
    949
       *
    950
       * - input must fit into 88 bits
    951
       */
    952
      function toInt88(int256 value) internal pure returns (int88 downcasted) {
    953
        downcasted = int88(value);
    954
        if (downcasted != value) {
    955
          revert SafeCastOverflowedIntDowncast(88, value);
    956
        }
    957
      }
    958
    959
      /**
    960
       * @dev Returns the downcasted int80 from int256, reverting on
    961
       * overflow (when the input is less than smallest int80 or
    962
       * greater than largest int80).
    963
       *
    964
       * Counterpart to Solidity's `int80` operator.
    965
       *
    966
       * Requirements:
    967
       *
    968
       * - input must fit into 80 bits
    969
       */
    970
      function toInt80(int256 value) internal pure returns (int80 downcasted) {
    971
        downcasted = int80(value);
    972
        if (downcasted != value) {
    973
          revert SafeCastOverflowedIntDowncast(80, value);
    974
        }
    975
      }
    976
    977
      /**
    978
       * @dev Returns the downcasted int72 from int256, reverting on
    979
       * overflow (when the input is less than smallest int72 or
    980
       * greater than largest int72).
    981
       *
    982
       * Counterpart to Solidity's `int72` operator.
    983
       *
    984
       * Requirements:
    985
       *
    986
       * - input must fit into 72 bits
    987
       */
    988
      function toInt72(int256 value) internal pure returns (int72 downcasted) {
    989
        downcasted = int72(value);
    990
        if (downcasted != value) {
    991
          revert SafeCastOverflowedIntDowncast(72, value);
    992
        }
    993
      }
    994
    995
      /**
    996
       * @dev Returns the downcasted int64 from int256, reverting on
    997
       * overflow (when the input is less than smallest int64 or
    998
       * greater than largest int64).
    999
       *
    1000
       * Counterpart to Solidity's `int64` operator.
    1001
       *
    1002
       * Requirements:
    1003
       *
    1004
       * - input must fit into 64 bits
    1005
       */
    1006
      function toInt64(int256 value) internal pure returns (int64 downcasted) {
    1007
        downcasted = int64(value);
    1008
        if (downcasted != value) {
    1009
          revert SafeCastOverflowedIntDowncast(64, value);
    1010
        }
    1011
      }
    1012
    1013
      /**
    1014
       * @dev Returns the downcasted int56 from int256, reverting on
    1015
       * overflow (when the input is less than smallest int56 or
    1016
       * greater than largest int56).
    1017
       *
    1018
       * Counterpart to Solidity's `int56` operator.
    1019
       *
    1020
       * Requirements:
    1021
       *
    1022
       * - input must fit into 56 bits
    1023
       */
    1024
      function toInt56(int256 value) internal pure returns (int56 downcasted) {
    1025
        downcasted = int56(value);
    1026
        if (downcasted != value) {
    1027
          revert SafeCastOverflowedIntDowncast(56, value);
    1028
        }
    1029
      }
    1030
    1031
      /**
    1032
       * @dev Returns the downcasted int48 from int256, reverting on
    1033
       * overflow (when the input is less than smallest int48 or
    1034
       * greater than largest int48).
    1035
       *
    1036
       * Counterpart to Solidity's `int48` operator.
    1037
       *
    1038
       * Requirements:
    1039
       *
    1040
       * - input must fit into 48 bits
    1041
       */
    1042
      function toInt48(int256 value) internal pure returns (int48 downcasted) {
    1043
        downcasted = int48(value);
    1044
        if (downcasted != value) {
    1045
          revert SafeCastOverflowedIntDowncast(48, value);
    1046
        }
    1047
      }
    1048
    1049
      /**
    1050
       * @dev Returns the downcasted int40 from int256, reverting on
    1051
       * overflow (when the input is less than smallest int40 or
    1052
       * greater than largest int40).
    1053
       *
    1054
       * Counterpart to Solidity's `int40` operator.
    1055
       *
    1056
       * Requirements:
    1057
       *
    1058
       * - input must fit into 40 bits
    1059
       */
    1060
      function toInt40(int256 value) internal pure returns (int40 downcasted) {
    1061
        downcasted = int40(value);
    1062
        if (downcasted != value) {
    1063
          revert SafeCastOverflowedIntDowncast(40, value);
    1064
        }
    1065
      }
    1066
    1067
      /**
    1068
       * @dev Returns the downcasted int32 from int256, reverting on
    1069
       * overflow (when the input is less than smallest int32 or
    1070
       * greater than largest int32).
    1071
       *
    1072
       * Counterpart to Solidity's `int32` operator.
    1073
       *
    1074
       * Requirements:
    1075
       *
    1076
       * - input must fit into 32 bits
    1077
       */
    1078
      function toInt32(int256 value) internal pure returns (int32 downcasted) {
    1079
        downcasted = int32(value);
    1080
        if (downcasted != value) {
    1081
          revert SafeCastOverflowedIntDowncast(32, value);
    1082
        }
    1083
      }
    1084
    1085
      /**
    1086
       * @dev Returns the downcasted int24 from int256, reverting on
    1087
       * overflow (when the input is less than smallest int24 or
    1088
       * greater than largest int24).
    1089
       *
    1090
       * Counterpart to Solidity's `int24` operator.
    1091
       *
    1092
       * Requirements:
    1093
       *
    1094
       * - input must fit into 24 bits
    1095
       */
    1096
      function toInt24(int256 value) internal pure returns (int24 downcasted) {
    1097
        downcasted = int24(value);
    1098
        if (downcasted != value) {
    1099
          revert SafeCastOverflowedIntDowncast(24, value);
    1100
        }
    1101
      }
    1102
    1103
      /**
    1104
       * @dev Returns the downcasted int16 from int256, reverting on
    1105
       * overflow (when the input is less than smallest int16 or
    1106
       * greater than largest int16).
    1107
       *
    1108
       * Counterpart to Solidity's `int16` operator.
    1109
       *
    1110
       * Requirements:
    1111
       *
    1112
       * - input must fit into 16 bits
    1113
       */
    1114
      function toInt16(int256 value) internal pure returns (int16 downcasted) {
    1115
        downcasted = int16(value);
    1116
        if (downcasted != value) {
    1117
          revert SafeCastOverflowedIntDowncast(16, value);
    1118
        }
    1119
      }
    1120
    1121
      /**
    1122
       * @dev Returns the downcasted int8 from int256, reverting on
    1123
       * overflow (when the input is less than smallest int8 or
    1124
       * greater than largest int8).
    1125
       *
    1126
       * Counterpart to Solidity's `int8` operator.
    1127
       *
    1128
       * Requirements:
    1129
       *
    1130
       * - input must fit into 8 bits
    1131
       */
    1132
      function toInt8(int256 value) internal pure returns (int8 downcasted) {
    1133
        downcasted = int8(value);
    1134
        if (downcasted != value) {
    1135
          revert SafeCastOverflowedIntDowncast(8, value);
    1136
        }
    1137
      }
    1138
    1139
      /**
    1140
       * @dev Converts an unsigned uint256 into a signed int256.
    1141
       *
    1142
       * Requirements:
    1143
       *
    1144
       * - input must be less than or equal to maxInt256.
    1145
       */
    1146
      function toInt256(uint256 value) internal pure returns (int256) {
    1147
        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
    1148
        if (value > uint256(type(int256).max)) {
    1149
          revert SafeCastOverflowedUintToInt(value);
    1150
        }
    1151
        return int256(value);
    1152
      }
    1153
    1154
      /**
    1155
       * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.
    1156
       */
    1157
      function toUint(bool b) internal pure returns (uint256 u) {
    1158
        assembly ('memory-safe') {
    1159
          u := iszero(iszero(b))
    1160
        }
    1161
      }
    1162
    }
    1163
    0.0% src/dependencies/openzeppelin/SafeERC20.sol
    Lines covered: 0 / 5 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.3.0) (token/ERC20/utils/SafeERC20.sol)
    3
    4
    pragma solidity ^0.8.20;
    5
    6
    import {IERC20} from './IERC20.sol';
    7
    import {IERC1363} from './IERC1363.sol';
    8
    9
    /**
    10
     * @title SafeERC20
    11
     * @dev Wrappers around ERC-20 operations that throw on failure (when the token
    12
     * contract returns false). Tokens that return no value (and instead revert or
    13
     * throw on failure) are also supported, non-reverting calls are assumed to be
    14
     * successful.
    15
     * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
    16
     * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
    17
     */
    18
    library SafeERC20 {
    19
      /**
    20
       * @dev An operation with an ERC-20 token failed.
    21
       */
    22
      error SafeERC20FailedOperation(address token);
    23
    24
      /**
    25
       * @dev Indicates a failed `decreaseAllowance` request.
    26
       */
    27
      error SafeERC20FailedDecreaseAllowance(
    28
        address spender,
    29
        uint256 currentAllowance,
    30
        uint256 requestedDecrease
    31
      );
    32
    33
      /**
    34
       * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
    35
       * non-reverting calls are assumed to be successful.
    36
       */
    37
      function safeTransfer(IERC20 token, address to, uint256 value) internal {
    38
        _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
    39
      }
    40
    41
      /**
    42
       * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
    43
       * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
    44
       */
    45
      function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
    46
        _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
    47
      }
    48
    49
      /**
    50
       * @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.
    51
       */
    52
      function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {
    53
        return _callOptionalReturnBool(token, abi.encodeCall(token.transfer, (to, value)));
    54
      }
    55
    56
      /**
    57
       * @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.
    58
       */
    59
      function trySafeTransferFrom(
    60
        IERC20 token,
    61
        address from,
    62
        address to,
    63
        uint256 value
    64
      ) internal returns (bool) {
    65
        return _callOptionalReturnBool(token, abi.encodeCall(token.transferFrom, (from, to, value)));
    66
      }
    67
    68
      /**
    69
       * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
    70
       * non-reverting calls are assumed to be successful.
    71
       *
    72
       * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
    73
       * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
    74
       * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
    75
       * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
    76
       */
    77
      function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
    78
        uint256 oldAllowance = token.allowance(address(this), spender);
    79
        forceApprove(token, spender, oldAllowance + value);
    80
      }
    81
    82
      /**
    83
       * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
    84
       * value, non-reverting calls are assumed to be successful.
    85
       *
    86
       * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
    87
       * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
    88
       * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
    89
       * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
    90
       */
    91
      function safeDecreaseAllowance(
    92
        IERC20 token,
    93
        address spender,
    94
        uint256 requestedDecrease
    95
      ) internal {
    96
        unchecked {
    97
          uint256 currentAllowance = token.allowance(address(this), spender);
    98
          if (currentAllowance < requestedDecrease) {
    99
            revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
    100
          }
    101
          forceApprove(token, spender, currentAllowance - requestedDecrease);
    102
        }
    103
      }
    104
    105
      /**
    106
       * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
    107
       * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
    108
       * to be set to zero before setting it to a non-zero value, such as USDT.
    109
       *
    110
       * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function
    111
       * only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being
    112
       * set here.
    113
       */
    114
      function forceApprove(IERC20 token, address spender, uint256 value) internal {
    115
        bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
    116
    117
        if (!_callOptionalReturnBool(token, approvalCall)) {
    118
          _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
    119
          _callOptionalReturn(token, approvalCall);
    120
        }
    121
      }
    122
    123
      /**
    124
       * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no
    125
       * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
    126
       * targeting contracts.
    127
       *
    128
       * Reverts if the returned value is other than `true`.
    129
       */
    130
      function transferAndCallRelaxed(
    131
        IERC1363 token,
    132
        address to,
    133
        uint256 value,
    134
        bytes memory data
    135
      ) internal {
    136
        if (to.code.length == 0) {
    137
          safeTransfer(token, to, value);
    138
        } else if (!token.transferAndCall(to, value, data)) {
    139
          revert SafeERC20FailedOperation(address(token));
    140
        }
    141
      }
    142
    143
      /**
    144
       * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target
    145
       * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
    146
       * targeting contracts.
    147
       *
    148
       * Reverts if the returned value is other than `true`.
    149
       */
    150
      function transferFromAndCallRelaxed(
    151
        IERC1363 token,
    152
        address from,
    153
        address to,
    154
        uint256 value,
    155
        bytes memory data
    156
      ) internal {
    157
        if (to.code.length == 0) {
    158
          safeTransferFrom(token, from, to, value);
    159
        } else if (!token.transferFromAndCall(from, to, value, data)) {
    160
          revert SafeERC20FailedOperation(address(token));
    161
        }
    162
      }
    163
    164
      /**
    165
       * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no
    166
       * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
    167
       * targeting contracts.
    168
       *
    169
       * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.
    170
       * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}
    171
       * once without retrying, and relies on the returned value to be true.
    172
       *
    173
       * Reverts if the returned value is other than `true`.
    174
       */
    175
      function approveAndCallRelaxed(
    176
        IERC1363 token,
    177
        address to,
    178
        uint256 value,
    179
        bytes memory data
    180
      ) internal {
    181
        if (to.code.length == 0) {
    182
          forceApprove(token, to, value);
    183
        } else if (!token.approveAndCall(to, value, data)) {
    184
          revert SafeERC20FailedOperation(address(token));
    185
        }
    186
      }
    187
    188
      /**
    189
       * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
    190
       * on the return value: the return value is optional (but if data is returned, it must not be false).
    191
       * @param token The token targeted by the call.
    192
       * @param data The call data (encoded using abi.encode or one of its variants).
    193
       *
    194
       * This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements.
    195
       */
    196
      function _callOptionalReturn(IERC20 token, bytes memory data) private {
    197
        uint256 returnSize;
    198
        uint256 returnValue;
    199
        assembly ('memory-safe') {
    200
          let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
    201
          // bubble errors
    202
          if iszero(success) {
    203
            let ptr := mload(0x40)
    204
            returndatacopy(ptr, 0, returndatasize())
    205
            revert(ptr, returndatasize())
    206
          }
    207
          returnSize := returndatasize()
    208
          returnValue := mload(0)
    209
        }
    210
    211
        if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {
    212
          revert SafeERC20FailedOperation(address(token));
    213
        }
    214
      }
    215
    216
      /**
    217
       * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
    218
       * on the return value: the return value is optional (but if data is returned, it must not be false).
    219
       * @param token The token targeted by the call.
    220
       * @param data The call data (encoded using abi.encode or one of its variants).
    221
       *
    222
       * This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead.
    223
       */
    224
      function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
    225
        bool success;
    226
        uint256 returnSize;
    227
        uint256 returnValue;
    228
        assembly ('memory-safe') {
    229
          success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
    230
          returnSize := returndatasize()
    231
          returnValue := mload(0)
    232
        }
    233
        return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);
    234
      }
    235
    }
    236
    0.0% src/dependencies/openzeppelin/SignatureChecker.sol
    Lines covered: 0 / 7 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.4.0) (utils/cryptography/SignatureChecker.sol)
    3
    4
    pragma solidity ^0.8.24;
    5
    6
    import {ECDSA} from './ECDSA.sol';
    7
    import {IERC1271} from './IERC1271.sol';
    8
    import {IERC7913SignatureVerifier} from './IERC7913.sol';
    9
    import {Bytes} from './Bytes.sol';
    10
    11
    /**
    12
     * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support:
    13
     *
    14
     * * ECDSA signatures from externally owned accounts (EOAs)
    15
     * * ERC-1271 signatures from smart contract wallets like Argent and Safe Wallet (previously Gnosis Safe)
    16
     * * ERC-7913 signatures from keys that do not have an Ethereum address of their own
    17
     *
    18
     * See https://eips.ethereum.org/EIPS/eip-1271[ERC-1271] and https://eips.ethereum.org/EIPS/eip-7913[ERC-7913].
    19
     */
    20
    library SignatureChecker {
    21
      using Bytes for bytes;
    22
    23
      /**
    24
       * @dev Checks if a signature is valid for a given signer and data hash. If the signer has code, the
    25
       * signature is validated against it using ERC-1271, otherwise it's validated using `ECDSA.recover`.
    26
       *
    27
       * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus
    28
       * change through time. It could return true at block N and false at block N+1 (or the opposite).
    29
       *
    30
       * NOTE: For an extended version of this function that supports ERC-7913 signatures, see {isValidSignatureNow-bytes-bytes32-bytes-}.
    31
       */
    32
      function isValidSignatureNow(
    33
        address signer,
    34
        bytes32 hash,
    35
        bytes memory signature
    36
      ) internal view returns (bool) {
    37
        if (signer.code.length == 0) {
    38
          (address recovered, ECDSA.RecoverError err, ) = ECDSA.tryRecover(hash, signature);
    39
          return err == ECDSA.RecoverError.NoError && recovered == signer;
    40
        } else {
    41
          return isValidERC1271SignatureNow(signer, hash, signature);
    42
        }
    43
      }
    44
    45
      /**
    46
       * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated
    47
       * against the signer smart contract using ERC-1271.
    48
       *
    49
       * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus
    50
       * change through time. It could return true at block N and false at block N+1 (or the opposite).
    51
       */
    52
      function isValidERC1271SignatureNow(
    53
        address signer,
    54
        bytes32 hash,
    55
        bytes memory signature
    56
      ) internal view returns (bool) {
    57
        (bool success, bytes memory result) = signer.staticcall(
    58
          abi.encodeCall(IERC1271.isValidSignature, (hash, signature))
    59
        );
    60
        return (success &&
    61
          result.length >= 32 &&
    62
          abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));
    63
      }
    64
    65
      /**
    66
       * @dev Verifies a signature for a given ERC-7913 signer and hash.
    67
       *
    68
       * The signer is a `bytes` object that is the concatenation of an address and optionally a key:
    69
       * `verifier || key`. A signer must be at least 20 bytes long.
    70
       *
    71
       * Verification is done as follows:
    72
       *
    73
       * * If `signer.length < 20`: verification fails
    74
       * * If `signer.length == 20`: verification is done using {isValidSignatureNow}
    75
       * * Otherwise: verification is done using {IERC7913SignatureVerifier}
    76
       *
    77
       * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus
    78
       * change through time. It could return true at block N and false at block N+1 (or the opposite).
    79
       */
    80
      function isValidSignatureNow(
    81
        bytes memory signer,
    82
        bytes32 hash,
    83
        bytes memory signature
    84
      ) internal view returns (bool) {
    85
        if (signer.length < 20) {
    86
          return false;
    87
        } else if (signer.length == 20) {
    88
          return isValidSignatureNow(address(bytes20(signer)), hash, signature);
    89
        } else {
    90
          (bool success, bytes memory result) = address(bytes20(signer)).staticcall(
    91
            abi.encodeCall(IERC7913SignatureVerifier.verify, (signer.slice(20), hash, signature))
    92
          );
    93
          return (success &&
    94
            result.length >= 32 &&
    95
            abi.decode(result, (bytes32)) == bytes32(IERC7913SignatureVerifier.verify.selector));
    96
        }
    97
      }
    98
    99
      /**
    100
       * @dev Verifies multiple ERC-7913 `signatures` for a given `hash` using a set of `signers`.
    101
       * Returns `false` if the number of signers and signatures is not the same.
    102
       *
    103
       * The signers should be ordered by their `keccak256` hash to ensure efficient duplication check. Unordered
    104
       * signers are supported, but the uniqueness check will be more expensive.
    105
       *
    106
       * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus
    107
       * change through time. It could return true at block N and false at block N+1 (or the opposite).
    108
       */
    109
      function areValidSignaturesNow(
    110
        bytes32 hash,
    111
        bytes[] memory signers,
    112
        bytes[] memory signatures
    113
      ) internal view returns (bool) {
    114
        if (signers.length != signatures.length) return false;
    115
    116
        bytes32 lastId = bytes32(0);
    117
    118
        for (uint256 i = 0; i < signers.length; ++i) {
    119
          bytes memory signer = signers[i];
    120
    121
          // If one of the signatures is invalid, reject the batch
    122
          if (!isValidSignatureNow(signer, hash, signatures[i])) return false;
    123
    124
          bytes32 id = keccak256(signer);
    125
          // If the current signer ID is greater than all previous IDs, then this is a new signer.
    126
          if (lastId < id) {
    127
            lastId = id;
    128
          } else {
    129
            // If this signer id is not greater than all the previous ones, verify that it is not a duplicate of a previous one
    130
            // This loop is never executed if the signers are ordered by id.
    131
            for (uint256 j = 0; j < i; ++j) {
    132
              if (id == keccak256(signers[j])) return false;
    133
            }
    134
          }
    135
        }
    136
    137
        return true;
    138
      }
    139
    }
    140
    33.0% src/dependencies/openzeppelin/SlotDerivation.sol
    Lines covered: 2 / 6 (33.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.3.0) (utils/SlotDerivation.sol)
    3
    // This file was procedurally generated from scripts/generate/templates/SlotDerivation.js.
    4
    5
    pragma solidity ^0.8.20;
    6
    7
    /**
    8
     * @dev Library for computing storage (and transient storage) locations from namespaces and deriving slots
    9
     * corresponding to standard patterns. The derivation method for array and mapping matches the storage layout used by
    10
     * the solidity language / compiler.
    11
     *
    12
     * See https://docs.soliditylang.org/en/v0.8.20/internals/layout_in_storage.html#mappings-and-dynamic-arrays[Solidity docs for mappings and dynamic arrays.].
    13
     *
    14
     * Example usage:
    15
     * ```solidity
    16
     * contract Example {
    17
     *     // Add the library methods
    18
     *     using StorageSlot for bytes32;
    19
     *     using SlotDerivation for bytes32;
    20
     *
    21
     *     // Declare a namespace
    22
     *     string private constant _NAMESPACE = "<namespace>"; // eg. OpenZeppelin.Slot
    23
     *
    24
     *     function setValueInNamespace(uint256 key, address newValue) internal {
    25
     *         _NAMESPACE.erc7201Slot().deriveMapping(key).getAddressSlot().value = newValue;
    26
     *     }
    27
     *
    28
     *     function getValueInNamespace(uint256 key) internal view returns (address) {
    29
     *         return _NAMESPACE.erc7201Slot().deriveMapping(key).getAddressSlot().value;
    30
     *     }
    31
     * }
    32
     * ```
    33
     *
    34
     * TIP: Consider using this library along with {StorageSlot}.
    35
     *
    36
     * NOTE: This library provides a way to manipulate storage locations in a non-standard way. Tooling for checking
    37
     * upgrade safety will ignore the slots accessed through this library.
    38
     *
    39
     * _Available since v5.1._
    40
     */
    41
    library SlotDerivation {
    42
      /**
    43
       * @dev Derive an ERC-7201 slot from a string (namespace).
    44
       */
    45
      function erc7201Slot(string memory namespace) internal pure returns (bytes32 slot) {
    46
        assembly ('memory-safe') {
    47
          mstore(0x00, sub(keccak256(add(namespace, 0x20), mload(namespace)), 1))
    48
          slot := and(keccak256(0x00, 0x20), not(0xff))
    49
        }
    50
      }
    51
    52
      /**
    53
       * @dev Add an offset to a slot to get the n-th element of a structure or an array.
    54
       */
    55
      function offset(bytes32 slot, uint256 pos) internal pure returns (bytes32 result) {
    56
        unchecked {
    57
          return bytes32(uint256(slot) + pos);
    58
        }
    59
      }
    60
    61
      /**
    62
       * @dev Derive the location of the first element in an array from the slot where the length is stored.
    63
       */
    64
      function deriveArray(bytes32 slot) internal pure returns (bytes32 result) {
    65
        assembly ('memory-safe') {
    66
          mstore(0x00, slot)
    67
          result := keccak256(0x00, 0x20)
    68
        }
    69
      }
    70
    71
      /**
    72
       * @dev Derive the location of a mapping element from the key.
    73
       */
    74
      function deriveMapping(bytes32 slot, address key) internal pure returns (bytes32 result) {
    75
        assembly ('memory-safe') {
    76
          mstore(0x00, and(key, shr(96, not(0))))
    77
          mstore(0x20, slot)
    78
          result := keccak256(0x00, 0x40)
    79
        }
    80
      }
    81
    82
      /**
    83
       * @dev Derive the location of a mapping element from the key.
    84
       */
    85
      function deriveMapping(bytes32 slot, bool key) internal pure returns (bytes32 result) {
    86
        assembly ('memory-safe') {
    87
          mstore(0x00, iszero(iszero(key)))
    88
          mstore(0x20, slot)
    89
          result := keccak256(0x00, 0x40)
    90
        }
    91
      }
    92
    93
      /**
    94
       * @dev Derive the location of a mapping element from the key.
    95
       */
    96
      function deriveMapping(bytes32 slot, bytes32 key) internal pure returns (bytes32 result) {
    97
        assembly ('memory-safe') {
    98
          mstore(0x00, key)
    99
          mstore(0x20, slot)
    100
          result := keccak256(0x00, 0x40)
    101
        }
    102
      }
    103
    104
      /**
    105
       * @dev Derive the location of a mapping element from the key.
    106
       */
    107
      function deriveMapping(bytes32 slot, uint256 key) internal pure returns (bytes32 result) {
    108
        assembly ('memory-safe') {
    109
          mstore(0x00, key)
    110
          mstore(0x20, slot)
    111
          result := keccak256(0x00, 0x40)
    112
        }
    113
      }
    114
    115
      /**
    116
       * @dev Derive the location of a mapping element from the key.
    117
       */
    118
      function deriveMapping(bytes32 slot, int256 key) internal pure returns (bytes32 result) {
    119
        assembly ('memory-safe') {
    120
          mstore(0x00, key)
    121
          mstore(0x20, slot)
    122
          result := keccak256(0x00, 0x40)
    123
        }
    124
      }
    125
    126
      /**
    127
       * @dev Derive the location of a mapping element from the key.
    128
       */
    129
      function deriveMapping(bytes32 slot, string memory key) internal pure returns (bytes32 result) {
    130
        assembly ('memory-safe') {
    131
          let length := mload(key)
    132
          let begin := add(key, 0x20)
    133
          let end := add(begin, length)
    134
          let cache := mload(end)
    135
          mstore(end, slot)
    136
          result := keccak256(begin, add(length, 0x20))
    137
          mstore(end, cache)
    138
        }
    139
      }
    140
    141
      /**
    142
       * @dev Derive the location of a mapping element from the key.
    143
       */
    144
      function deriveMapping(bytes32 slot, bytes memory key) internal pure returns (bytes32 result) {
    145
        assembly ('memory-safe') {
    146
          let length := mload(key)
    147
          let begin := add(key, 0x20)
    148
          let end := add(begin, length)
    149
          let cache := mload(end)
    150
          mstore(end, slot)
    151
          result := keccak256(begin, add(length, 0x20))
    152
          mstore(end, cache)
    153
        }
    154
      }
    155
    }
    156
    70.0% src/dependencies/openzeppelin/StorageSlot.sol
    Lines covered: 7 / 10 (70.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.1.0) (utils/StorageSlot.sol)
    3
    // This file was procedurally generated from scripts/generate/templates/StorageSlot.js.
    4
    5
    pragma solidity ^0.8.20;
    6
    7
    /**
    8
     * @dev Library for reading and writing primitive types to specific storage slots.
    9
     *
    10
     * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
    11
     * This library helps with reading and writing to such slots without the need for inline assembly.
    12
     *
    13
     * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
    14
     *
    15
     * Example usage to set ERC-1967 implementation slot:
    16
     * ```solidity
    17
     * contract ERC1967 {
    18
     *     // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.
    19
     *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
    20
     *
    21
     *     function _getImplementation() internal view returns (address) {
    22
     *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
    23
     *     }
    24
     *
    25
     *     function _setImplementation(address newImplementation) internal {
    26
     *         require(newImplementation.code.length > 0);
    27
     *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
    28
     *     }
    29
     * }
    30
     * ```
    31
     *
    32
     * TIP: Consider using this library along with {SlotDerivation}.
    33
     */
    34
    library StorageSlot {
    35
      struct AddressSlot {
    36
        address value;
    37
      }
    38
    39
      struct BooleanSlot {
    40
        bool value;
    41
      }
    42
    43
      struct Bytes32Slot {
    44
        bytes32 value;
    45
      }
    46
    47
      struct Uint256Slot {
    48
        uint256 value;
    49
      }
    50
    51
      struct Int256Slot {
    52
        int256 value;
    53
      }
    54
    55
      struct StringSlot {
    56
        string value;
    57
      }
    58
    59
      struct BytesSlot {
    60
        bytes value;
    61
      }
    62
    63
      /**
    64
       * @dev Returns an `AddressSlot` with member `value` located at `slot`.
    65
       */
    66
      function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
    67
        assembly ('memory-safe') {
    68
          r.slot := slot
    69
        }
    70
      }
    71
    72
      /**
    73
       * @dev Returns a `BooleanSlot` with member `value` located at `slot`.
    74
       */
    75
      function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
    76
        assembly ('memory-safe') {
    77
          r.slot := slot
    78
        }
    79
      }
    80
    81
      /**
    82
       * @dev Returns a `Bytes32Slot` with member `value` located at `slot`.
    83
       */
    84
      function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
    85
        assembly ('memory-safe') {
    86
          r.slot := slot
    87
        }
    88
      }
    89
    90
      /**
    91
       * @dev Returns a `Uint256Slot` with member `value` located at `slot`.
    92
       */
    93
      function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
    94
        assembly ('memory-safe') {
    95
          r.slot := slot
    96
        }
    97
      }
    98
    99
      /**
    100
       * @dev Returns a `Int256Slot` with member `value` located at `slot`.
    101
       */
    102
      function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) {
    103
        assembly ('memory-safe') {
    104
          r.slot := slot
    105
        }
    106
      }
    107
    108
      /**
    109
       * @dev Returns a `StringSlot` with member `value` located at `slot`.
    110
       */
    111
      function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
    112
        assembly ('memory-safe') {
    113
          r.slot := slot
    114
        }
    115
      }
    116
    117
      /**
    118
       * @dev Returns an `StringSlot` representation of the string storage pointer `store`.
    119
       */
    120
      function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
    121
        assembly ('memory-safe') {
    122
          r.slot := store.slot
    123
        }
    124
      }
    125
    126
      /**
    127
       * @dev Returns a `BytesSlot` with member `value` located at `slot`.
    128
       */
    129
      function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
    130
        assembly ('memory-safe') {
    131
          r.slot := slot
    132
        }
    133
      }
    134
    135
      /**
    136
       * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
    137
       */
    138
      function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
    139
        assembly ('memory-safe') {
    140
          r.slot := store.slot
    141
        }
    142
      }
    143
    }
    144
    8.0% src/dependencies/openzeppelin/Time.sol
    Lines covered: 1 / 12 (8.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.1.0) (utils/types/Time.sol)
    3
    4
    pragma solidity ^0.8.20;
    5
    6
    import {Math} from './Math.sol';
    7
    import {SafeCast} from './SafeCast.sol';
    8
    9
    /**
    10
     * @dev This library provides helpers for manipulating time-related objects.
    11
     *
    12
     * It uses the following types:
    13
     * - `uint48` for timepoints
    14
     * - `uint32` for durations
    15
     *
    16
     * While the library doesn't provide specific types for timepoints and duration, it does provide:
    17
     * - a `Delay` type to represent duration that can be programmed to change value automatically at a given point
    18
     * - additional helper functions
    19
     */
    20
    library Time {
    21
      using Time for *;
    22
    23
      /**
    24
       * @dev Get the block timestamp as a Timepoint.
    25
       */
    26
      function timestamp() internal view returns (uint48) {
    27
        return SafeCast.toUint48(block.timestamp);
    28
      }
    29
    30
      /**
    31
       * @dev Get the block number as a Timepoint.
    32
       */
    33
      function blockNumber() internal view returns (uint48) {
    34
        return SafeCast.toUint48(block.number);
    35
      }
    36
    37
      // ==================================================== Delay =====================================================
    38
      /**
    39
       * @dev A `Delay` is a uint32 duration that can be programmed to change value automatically at a given point in the
    40
       * future. The "effect" timepoint describes when the transitions happens from the "old" value to the "new" value.
    41
       * This allows updating the delay applied to some operation while keeping some guarantees.
    42
       *
    43
       * In particular, the {update} function guarantees that if the delay is reduced, the old delay still applies for
    44
       * some time. For example if the delay is currently 7 days to do an upgrade, the admin should not be able to set
    45
       * the delay to 0 and upgrade immediately. If the admin wants to reduce the delay, the old delay (7 days) should
    46
       * still apply for some time.
    47
       *
    48
       *
    49
       * The `Delay` type is 112 bits long, and packs the following:
    50
       *
    51
       * ```
    52
       *   | [uint48]: effect date (timepoint)
    53
       *   |           | [uint32]: value before (duration)
    54
       *   ↓           ↓       ↓ [uint32]: value after (duration)
    55
       * 0xAAAAAAAAAAAABBBBBBBBCCCCCCCC
    56
       * ```
    57
       *
    58
       * NOTE: The {get} and {withUpdate} functions operate using timestamps. Block number based delays are not currently
    59
       * supported.
    60
       */
    61
      type Delay is uint112;
    62
    63
      /**
    64
       * @dev Wrap a duration into a Delay to add the one-step "update in the future" feature
    65
       */
    66
      function toDelay(uint32 duration) internal pure returns (Delay) {
    67
        return Delay.wrap(duration);
    68
      }
    69
    70
      /**
    71
       * @dev Get the value at a given timepoint plus the pending value and effect timepoint if there is a scheduled
    72
       * change after this timepoint. If the effect timepoint is 0, then the pending value should not be considered.
    73
       */
    74
      function _getFullAt(
    75
        Delay self,
    76
        uint48 timepoint
    77
      ) private pure returns (uint32 valueBefore, uint32 valueAfter, uint48 effect) {
    78
        (valueBefore, valueAfter, effect) = self.unpack();
    79
        return effect <= timepoint ? (valueAfter, 0, 0) : (valueBefore, valueAfter, effect);
    80
      }
    81
    82
      /**
    83
       * @dev Get the current value plus the pending value and effect timepoint if there is a scheduled change. If the
    84
       * effect timepoint is 0, then the pending value should not be considered.
    85
       */
    86
      function getFull(
    87
        Delay self
    88
      ) internal view returns (uint32 valueBefore, uint32 valueAfter, uint48 effect) {
    89
        return _getFullAt(self, timestamp());
    90
      }
    91
    92
      /**
    93
       * @dev Get the current value.
    94
       */
    95
      function get(Delay self) internal view returns (uint32) {
    96
        (uint32 delay, , ) = self.getFull();
    97
        return delay;
    98
      }
    99
    100
      /**
    101
       * @dev Update a Delay object so that it takes a new duration after a timepoint that is automatically computed to
    102
       * enforce the old delay at the moment of the update. Returns the updated Delay object and the timestamp when the
    103
       * new delay becomes effective.
    104
       */
    105
      function withUpdate(
    106
        Delay self,
    107
        uint32 newValue,
    108
        uint32 minSetback
    109
      ) internal view returns (Delay updatedDelay, uint48 effect) {
    110
        uint32 value = self.get();
    111
        uint32 setback = uint32(Math.max(minSetback, value > newValue ? value - newValue : 0));
    112
        effect = timestamp() + setback;
    113
        return (pack(value, newValue, effect), effect);
    114
      }
    115
    116
      /**
    117
       * @dev Split a delay into its components: valueBefore, valueAfter and effect (transition timepoint).
    118
       */
    119
      function unpack(
    120
        Delay self
    121
      ) internal pure returns (uint32 valueBefore, uint32 valueAfter, uint48 effect) {
    122
        uint112 raw = Delay.unwrap(self);
    123
    124
        valueAfter = uint32(raw);
    125
        valueBefore = uint32(raw >> 32);
    126
        effect = uint48(raw >> 64);
    127
    128
        return (valueBefore, valueAfter, effect);
    129
      }
    130
    131
      /**
    132
       * @dev pack the components into a Delay object.
    133
       */
    134
      function pack(
    135
        uint32 valueBefore,
    136
        uint32 valueAfter,
    137
        uint48 effect
    138
      ) internal pure returns (Delay) {
    139
        return Delay.wrap((uint112(effect) << 64) | (uint112(valueBefore) << 32) | uint112(valueAfter));
    140
      }
    141
    }
    142
    14.0% src/dependencies/openzeppelin/TransientSlot.sol
    Lines covered: 1 / 7 (14.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.3.0) (utils/TransientSlot.sol)
    3
    // This file was procedurally generated from scripts/generate/templates/TransientSlot.js.
    4
    5
    pragma solidity ^0.8.24;
    6
    7
    /**
    8
     * @dev Library for reading and writing value-types to specific transient storage slots.
    9
     *
    10
     * Transient slots are often used to store temporary values that are removed after the current transaction.
    11
     * This library helps with reading and writing to such slots without the need for inline assembly.
    12
     *
    13
     *  * Example reading and writing values using transient storage:
    14
     * ```solidity
    15
     * contract Lock {
    16
     *     using TransientSlot for *;
    17
     *
    18
     *     // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.
    19
     *     bytes32 internal constant _LOCK_SLOT = 0xf4678858b2b588224636b8522b729e7722d32fc491da849ed75b3fdf3c84f542;
    20
     *
    21
     *     modifier locked() {
    22
     *         require(!_LOCK_SLOT.asBoolean().tload());
    23
     *
    24
     *         _LOCK_SLOT.asBoolean().tstore(true);
    25
     *         _;
    26
     *         _LOCK_SLOT.asBoolean().tstore(false);
    27
     *     }
    28
     * }
    29
     * ```
    30
     *
    31
     * TIP: Consider using this library along with {SlotDerivation}.
    32
     */
    33
    library TransientSlot {
    34
      /**
    35
       * @dev UDVT that represents a slot holding an address.
    36
       */
    37
      type AddressSlot is bytes32;
    38
    39
      /**
    40
       * @dev Cast an arbitrary slot to a AddressSlot.
    41
       */
    42
      function asAddress(bytes32 slot) internal pure returns (AddressSlot) {
    43
        return AddressSlot.wrap(slot);
    44
      }
    45
    46
      /**
    47
       * @dev UDVT that represents a slot holding a bool.
    48
       */
    49
      type BooleanSlot is bytes32;
    50
    51
      /**
    52
       * @dev Cast an arbitrary slot to a BooleanSlot.
    53
       */
    54
      function asBoolean(bytes32 slot) internal pure returns (BooleanSlot) {
    55
        return BooleanSlot.wrap(slot);
    56
      }
    57
    58
      /**
    59
       * @dev UDVT that represents a slot holding a bytes32.
    60
       */
    61
      type Bytes32Slot is bytes32;
    62
    63
      /**
    64
       * @dev Cast an arbitrary slot to a Bytes32Slot.
    65
       */
    66
      function asBytes32(bytes32 slot) internal pure returns (Bytes32Slot) {
    67
        return Bytes32Slot.wrap(slot);
    68
      }
    69
    70
      /**
    71
       * @dev UDVT that represents a slot holding a uint256.
    72
       */
    73
      type Uint256Slot is bytes32;
    74
    75
      /**
    76
       * @dev Cast an arbitrary slot to a Uint256Slot.
    77
       */
    78
      function asUint256(bytes32 slot) internal pure returns (Uint256Slot) {
    79
        return Uint256Slot.wrap(slot);
    80
      }
    81
    82
      /**
    83
       * @dev UDVT that represents a slot holding a int256.
    84
       */
    85
      type Int256Slot is bytes32;
    86
    87
      /**
    88
       * @dev Cast an arbitrary slot to a Int256Slot.
    89
       */
    90
      function asInt256(bytes32 slot) internal pure returns (Int256Slot) {
    91
        return Int256Slot.wrap(slot);
    92
      }
    93
    94
      /**
    95
       * @dev Load the value held at location `slot` in transient storage.
    96
       */
    97
      function tload(AddressSlot slot) internal view returns (address value) {
    98
        assembly ('memory-safe') {
    99
          value := tload(slot)
    100
        }
    101
      }
    102
    103
      /**
    104
       * @dev Store `value` at location `slot` in transient storage.
    105
       */
    106
      function tstore(AddressSlot slot, address value) internal {
    107
        assembly ('memory-safe') {
    108
          tstore(slot, value)
    109
        }
    110
      }
    111
    112
      /**
    113
       * @dev Load the value held at location `slot` in transient storage.
    114
       */
    115
      function tload(BooleanSlot slot) internal view returns (bool value) {
    116
        assembly ('memory-safe') {
    117
          value := tload(slot)
    118
        }
    119
      }
    120
    121
      /**
    122
       * @dev Store `value` at location `slot` in transient storage.
    123
       */
    124
      function tstore(BooleanSlot slot, bool value) internal {
    125
        assembly ('memory-safe') {
    126
          tstore(slot, value)
    127
        }
    128
      }
    129
    130
      /**
    131
       * @dev Load the value held at location `slot` in transient storage.
    132
       */
    133
      function tload(Bytes32Slot slot) internal view returns (bytes32 value) {
    134
        assembly ('memory-safe') {
    135
          value := tload(slot)
    136
        }
    137
      }
    138
    139
      /**
    140
       * @dev Store `value` at location `slot` in transient storage.
    141
       */
    142
      function tstore(Bytes32Slot slot, bytes32 value) internal {
    143
        assembly ('memory-safe') {
    144
          tstore(slot, value)
    145
        }
    146
      }
    147
    148
      /**
    149
       * @dev Load the value held at location `slot` in transient storage.
    150
       */
    151
      function tload(Uint256Slot slot) internal view returns (uint256 value) {
    152
        assembly ('memory-safe') {
    153
          value := tload(slot)
    154
        }
    155
      }
    156
    157
      /**
    158
       * @dev Store `value` at location `slot` in transient storage.
    159
       */
    160
      function tstore(Uint256Slot slot, uint256 value) internal {
    161
        assembly ('memory-safe') {
    162
          tstore(slot, value)
    163
        }
    164
      }
    165
    166
      /**
    167
       * @dev Load the value held at location `slot` in transient storage.
    168
       */
    169
      function tload(Int256Slot slot) internal view returns (int256 value) {
    170
        assembly ('memory-safe') {
    171
          value := tload(slot)
    172
        }
    173
      }
    174
    175
      /**
    176
       * @dev Store `value` at location `slot` in transient storage.
    177
       */
    178
      function tstore(Int256Slot slot, int256 value) internal {
    179
        assembly ('memory-safe') {
    180
          tstore(slot, value)
    181
        }
    182
      }
    183
    }
    184
    25.0% src/dependencies/openzeppelin/TransparentUpgradeableProxy.sol
    Lines covered: 1 / 4 (25.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.2.0) (proxy/transparent/TransparentUpgradeableProxy.sol)
    3
    4
    pragma solidity ^0.8.22;
    5
    6
    import {ERC1967Utils} from './ERC1967Utils.sol';
    7
    import {ERC1967Proxy} from './ERC1967Proxy.sol';
    8
    import {IERC1967} from './IERC1967.sol';
    9
    import {ProxyAdmin} from './ProxyAdmin.sol';
    10
    11
    /**
    12
     * @dev Interface for {TransparentUpgradeableProxy}. In order to implement transparency, {TransparentUpgradeableProxy}
    13
     * does not implement this interface directly, and its upgradeability mechanism is implemented by an internal dispatch
    14
     * mechanism. The compiler is unaware that these functions are implemented by {TransparentUpgradeableProxy} and will not
    15
     * include them in the ABI so this interface must be used to interact with it.
    16
     */
    17
    interface ITransparentUpgradeableProxy is IERC1967 {
    18
      /// @dev See {UUPSUpgradeable-upgradeToAndCall}
    19
      function upgradeToAndCall(address newImplementation, bytes calldata data) external payable;
    20
    }
    21
    22
    /**
    23
     * @dev This contract implements a proxy that is upgradeable through an associated {ProxyAdmin} instance.
    24
     *
    25
     * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector
    26
     * clashing], which can potentially be used in an attack, this contract uses the
    27
     * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two
    28
     * things that go hand in hand:
    29
     *
    30
     * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if
    31
     * that call matches the {ITransparentUpgradeableProxy-upgradeToAndCall} function exposed by the proxy itself.
    32
     * 2. If the admin calls the proxy, it can call the `upgradeToAndCall` function but any other call won't be forwarded to
    33
     * the implementation. If the admin tries to call a function on the implementation it will fail with an error indicating
    34
     * the proxy admin cannot fallback to the target implementation.
    35
     *
    36
     * These properties mean that the admin account can only be used for upgrading the proxy, so it's best if it's a
    37
     * dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to
    38
     * call a function from the proxy implementation. For this reason, the proxy deploys an instance of {ProxyAdmin} and
    39
     * allows upgrades only if they come through it. You should think of the `ProxyAdmin` instance as the administrative
    40
     * interface of the proxy, including the ability to change who can trigger upgrades by transferring ownership.
    41
     *
    42
     * NOTE: The real interface of this proxy is that defined in `ITransparentUpgradeableProxy`. This contract does not
    43
     * inherit from that interface, and instead `upgradeToAndCall` is implicitly implemented using a custom dispatch
    44
     * mechanism in `_fallback`. Consequently, the compiler will not produce an ABI for this contract. This is necessary to
    45
     * fully implement transparency without decoding reverts caused by selector clashes between the proxy and the
    46
     * implementation.
    47
     *
    48
     * NOTE: This proxy does not inherit from {Context} deliberately. The {ProxyAdmin} of this contract won't send a
    49
     * meta-transaction in any way, and any other meta-transaction setup should be made in the implementation contract.
    50
     *
    51
     * IMPORTANT: This contract avoids unnecessary storage reads by setting the admin only during construction as an
    52
     * immutable variable, preventing any changes thereafter. However, the admin slot defined in ERC-1967 can still be
    53
     * overwritten by the implementation logic pointed to by this proxy. In such cases, the contract may end up in an
    54
     * undesirable state where the admin slot is different from the actual admin. Relying on the value of the admin slot
    55
     * is generally fine if the implementation is trusted.
    56
     *
    57
     * WARNING: It is not recommended to extend this contract to add additional external functions. If you do so, the
    58
     * compiler will not check that there are no selector conflicts, due to the note above. A selector clash between any new
    59
     * function and the functions declared in {ITransparentUpgradeableProxy} will be resolved in favor of the new one. This
    60
     * could render the `upgradeToAndCall` function inaccessible, preventing upgradeability and compromising transparency.
    61
     */
    62
    contract TransparentUpgradeableProxy is ERC1967Proxy {
    63
      // An immutable address for the admin to avoid unnecessary SLOADs before each call
    64
      // at the expense of removing the ability to change the admin once it's set.
    65
      // This is acceptable if the admin is always a ProxyAdmin instance or similar contract
    66
      // with its own ability to transfer the permissions to another account.
    67
      address private immutable _admin;
    68
    69
      /**
    70
       * @dev The proxy caller is the current admin, and can't fallback to the proxy target.
    71
       */
    72
      error ProxyDeniedAdminAccess();
    73
    74
      /**
    75
       * @dev Initializes an upgradeable proxy managed by an instance of a {ProxyAdmin} with an `initialOwner`,
    76
       * backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in
    77
       * {ERC1967Proxy-constructor}.
    78
       */
    79
      constructor(
    80
        address _logic,
    81
        address initialOwner,
    82
        bytes memory _data
    83
      ) payable ERC1967Proxy(_logic, _data) {
    84
        _admin = address(new ProxyAdmin(initialOwner));
    85
        // Set the storage value and emit an event for ERC-1967 compatibility
    86
        ERC1967Utils.changeAdmin(_proxyAdmin());
    87
      }
    88
    89
      /**
    90
       * @dev Returns the admin of this proxy.
    91
       */
    92
      function _proxyAdmin() internal view virtual returns (address) {
    93
        return _admin;
    94
      }
    95
    96
      /**
    97
       * @dev If caller is the admin process the call internally, otherwise transparently fallback to the proxy behavior.
    98
       */
    99
      function _fallback() internal virtual override {
    100
        if (msg.sender == _proxyAdmin()) {
    101
          if (msg.sig != ITransparentUpgradeableProxy.upgradeToAndCall.selector) {
    102
            revert ProxyDeniedAdminAccess();
    103
          } else {
    104
            _dispatchUpgradeToAndCall();
    105
          }
    106
        } else {
    107
          super._fallback();
    108
        }
    109
      }
    110
    111
      /**
    112
       * @dev Upgrade the implementation of the proxy. See {ERC1967Utils-upgradeToAndCall}.
    113
       *
    114
       * Requirements:
    115
       *
    116
       * - If `data` is empty, `msg.value` must be zero.
    117
       */
    118
      function _dispatchUpgradeToAndCall() private {
    119
        (address newImplementation, bytes memory data) = abi.decode(msg.data[4:], (address, bytes));
    120
        ERC1967Utils.upgradeToAndCall(newImplementation, data);
    121
      }
    122
    }
    123
    95.0% src/dependencies/openzeppelin-upgradeable/AccessManagedUpgradeable.sol
    Lines covered: 20 / 21 (95.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.4.0) (access/manager/AccessManaged.sol)
    3
    4
    pragma solidity ^0.8.20;
    5
    6
    import {AuthorityUtils} from 'src/dependencies/openzeppelin/AuthorityUtils.sol';
    7
    import {IAccessManager} from 'src/dependencies/openzeppelin/IAccessManager.sol';
    8
    import {IAccessManaged} from 'src/dependencies/openzeppelin/IAccessManaged.sol';
    9
    import {ContextUpgradeable} from './ContextUpgradeable.sol';
    10
    import {Initializable} from './Initializable.sol';
    11
    12
    /**
    13
     * @dev This contract module makes available a {restricted} modifier. Functions decorated with this modifier will be
    14
     * permissioned according to an "authority": a contract like {AccessManager} that follows the {IAuthority} interface,
    15
     * implementing a policy that allows certain callers to access certain functions.
    16
     *
    17
     * IMPORTANT: The `restricted` modifier should never be used on `internal` functions, judiciously used in `public`
    18
     * functions, and ideally only used in `external` functions. See {restricted}.
    19
     */
    20
    abstract contract AccessManagedUpgradeable is Initializable, ContextUpgradeable, IAccessManaged {
    21
      /// @custom:storage-location erc7201:openzeppelin.storage.AccessManaged
    22
      struct AccessManagedStorage {
    23
        address _authority;
    24
        bool _consumingSchedule;
    25
      }
    26
    27
      // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.AccessManaged")) - 1)) & ~bytes32(uint256(0xff))
    28
      bytes32 private constant AccessManagedStorageLocation =
    29
        0xf3177357ab46d8af007ab3fdb9af81da189e1068fefdc0073dca88a2cab40a00;
    30
    31
      function _getAccessManagedStorage() private pure returns (AccessManagedStorage storage $) {
    32
        assembly {
    33
          $.slot := AccessManagedStorageLocation
    34
        }
    35
      }
    36
    37
      /**
    38
       * @dev Initializes the contract connected to an initial authority.
    39
       */
    40
      function __AccessManaged_init(address initialAuthority) internal onlyInitializing {
    41
        __AccessManaged_init_unchained(initialAuthority);
    42
      }
    43
    44
      function __AccessManaged_init_unchained(address initialAuthority) internal onlyInitializing {
    45
        _setAuthority(initialAuthority);
    46
      }
    47
    48
      /**
    49
       * @dev Restricts access to a function as defined by the connected Authority for this contract and the
    50
       * caller and selector of the function that entered the contract.
    51
       *
    52
       * [IMPORTANT]
    53
       * ====
    54
       * In general, this modifier should only be used on `external` functions. It is okay to use it on `public`
    55
       * functions that are used as external entry points and are not called internally. Unless you know what you're
    56
       * doing, it should never be used on `internal` functions. Failure to follow these rules can have critical security
    57
       * implications! This is because the permissions are determined by the function that entered the contract, i.e. the
    58
       * function at the bottom of the call stack, and not the function where the modifier is visible in the source code.
    59
       * ====
    60
       *
    61
       * [WARNING]
    62
       * ====
    63
       * Avoid adding this modifier to the https://docs.soliditylang.org/en/v0.8.20/contracts.html#receive-ether-function[`receive()`]
    64
       * function or the https://docs.soliditylang.org/en/v0.8.20/contracts.html#fallback-function[`fallback()`]. These
    65
       * functions are the only execution paths where a function selector cannot be unambiguously determined from the calldata
    66
       * since the selector defaults to `0x00000000` in the `receive()` function and similarly in the `fallback()` function
    67
       * if no calldata is provided. (See {_checkCanCall}).
    68
       *
    69
       * The `receive()` function will always panic whereas the `fallback()` may panic depending on the calldata length.
    70
       * ====
    71
       */
    72
      modifier restricted() {
    73
        _checkCanCall(_msgSender(), _msgData());
    74
        _;
    75
      }
    76
    77
      /// @inheritdoc IAccessManaged
    78
      function authority() public view virtual returns (address) {
    79
        AccessManagedStorage storage $ = _getAccessManagedStorage();
    80
        return $._authority;
    81
      }
    82
    83
      /// @inheritdoc IAccessManaged
    84
      function setAuthority(address newAuthority) public virtual {
    85
        address caller = _msgSender();
    86
        if (caller != authority()) {
    87
          revert AccessManagedUnauthorized(caller);
    88
        }
    89
        if (newAuthority.code.length == 0) {
    90
          revert AccessManagedInvalidAuthority(newAuthority);
    91
        }
    92
        _setAuthority(newAuthority);
    93
      }
    94
    95
      /// @inheritdoc IAccessManaged
    96
      function isConsumingScheduledOp() public view returns (bytes4) {
    97
        AccessManagedStorage storage $ = _getAccessManagedStorage();
    98
        return $._consumingSchedule ? this.isConsumingScheduledOp.selector : bytes4(0);
    99
      }
    100
    101
      /**
    102
       * @dev Transfers control to a new authority. Internal function with no access restriction. Allows bypassing the
    103
       * permissions set by the current authority.
    104
       */
    105
      function _setAuthority(address newAuthority) internal virtual {
    106
        AccessManagedStorage storage $ = _getAccessManagedStorage();
    107
        $._authority = newAuthority;
    108
        emit AuthorityUpdated(newAuthority);
    109
      }
    110
    111
      /**
    112
       * @dev Reverts if the caller is not allowed to call the function identified by a selector. Panics if the calldata
    113
       * is less than 4 bytes long.
    114
       */
    115
      function _checkCanCall(address caller, bytes calldata data) internal virtual {
    116
        AccessManagedStorage storage $ = _getAccessManagedStorage();
    117
        (bool immediate, uint32 delay) = AuthorityUtils.canCallWithDelay(
    118
          authority(),
    119
          caller,
    120
          address(this),
    121
          bytes4(data[0:4])
    122
        );
    123
        if (!immediate) {
    124
          if (delay > 0) {
    125
            $._consumingSchedule = true;
    126
            IAccessManager(authority()).consumeScheduledOp(caller, data);
    127
            $._consumingSchedule = false;
    128
          } else {
    129
            revert AccessManagedUnauthorized(caller);
    130
          }
    131
        }
    132
      }
    133
    }
    134
    50.0% src/dependencies/openzeppelin-upgradeable/ContextUpgradeable.sol
    Lines covered: 1 / 2 (50.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
    3
    4
    pragma solidity ^0.8.20;
    5
    import {Initializable} from './Initializable.sol';
    6
    7
    /**
    8
     * @dev Provides information about the current execution context, including the
    9
     * sender of the transaction and its data. While these are generally available
    10
     * via msg.sender and msg.data, they should not be accessed in such a direct
    11
     * manner, since when dealing with meta-transactions the account sending and
    12
     * paying for execution may not be the actual sender (as far as an application
    13
     * is concerned).
    14
     *
    15
     * This contract is only required for intermediate, library-like contracts.
    16
     */
    17
    abstract contract ContextUpgradeable is Initializable {
    18
        function __Context_init() internal onlyInitializing {
    19
        }
    20
    21
        function __Context_init_unchained() internal onlyInitializing {
    22
        }
    23
        function _msgSender() internal view virtual returns (address) {
    24
            return msg.sender;
    25
        }
    26
    27
        function _msgData() internal view virtual returns (bytes calldata) {
    28
            return msg.data;
    29
        }
    30
    31
        function _contextSuffixLength() internal view virtual returns (uint256) {
    32
            return 0;
    33
        }
    34
    }
    35
    0.0% src/dependencies/openzeppelin-upgradeable/Initializable.sol
    Lines covered: 0 / 14 (0.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    // OpenZeppelin Contracts (last updated v5.3.0) (proxy/utils/Initializable.sol)
    3
    4
    pragma solidity ^0.8.20;
    5
    6
    /**
    7
     * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
    8
     * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
    9
     * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
    10
     * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
    11
     *
    12
     * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
    13
     * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
    14
     * case an upgrade adds a module that needs to be initialized.
    15
     *
    16
     * For example:
    17
     *
    18
     * [.hljs-theme-light.nopadding]
    19
     * ```solidity
    20
     * contract MyToken is ERC20Upgradeable {
    21
     *     function initialize() initializer public {
    22
     *         __ERC20_init("MyToken", "MTK");
    23
     *     }
    24
     * }
    25
     *
    26
     * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
    27
     *     function initializeV2() reinitializer(2) public {
    28
     *         __ERC20Permit_init("MyToken");
    29
     *     }
    30
     * }
    31
     * ```
    32
     *
    33
     * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
    34
     * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
    35
     *
    36
     * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
    37
     * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
    38
     *
    39
     * [CAUTION]
    40
     * ====
    41
     * Avoid leaving a contract uninitialized.
    42
     *
    43
     * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
    44
     * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
    45
     * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
    46
     *
    47
     * [.hljs-theme-light.nopadding]
    48
     * ```
    49
     * /// @custom:oz-upgrades-unsafe-allow constructor
    50
     * constructor() {
    51
     *     _disableInitializers();
    52
     * }
    53
     * ```
    54
     * ====
    55
     */
    56
    abstract contract Initializable {
    57
      /**
    58
       * @dev Storage of the initializable contract.
    59
       *
    60
       * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
    61
       * when using with upgradeable contracts.
    62
       *
    63
       * @custom:storage-location erc7201:openzeppelin.storage.Initializable
    64
       */
    65
      struct InitializableStorage {
    66
        /**
    67
         * @dev Indicates that the contract has been initialized.
    68
         */
    69
        uint64 _initialized;
    70
        /**
    71
         * @dev Indicates that the contract is in the process of being initialized.
    72
         */
    73
        bool _initializing;
    74
      }
    75
    76
      // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
    77
      bytes32 private constant INITIALIZABLE_STORAGE =
    78
        0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;
    79
    80
      /**
    81
       * @dev The contract is already initialized.
    82
       */
    83
      error InvalidInitialization();
    84
    85
      /**
    86
       * @dev The contract is not initializing.
    87
       */
    88
      error NotInitializing();
    89
    90
      /**
    91
       * @dev Triggered when the contract has been initialized or reinitialized.
    92
       */
    93
      event Initialized(uint64 version);
    94
    95
      /**
    96
       * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
    97
       * `onlyInitializing` functions can be used to initialize parent contracts.
    98
       *
    99
       * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any
    100
       * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
    101
       * production.
    102
       *
    103
       * Emits an {Initialized} event.
    104
       */
    105
      modifier initializer() {
    106
        // solhint-disable-next-line var-name-mixedcase
    107
        InitializableStorage storage $ = _getInitializableStorage();
    108
    109
        // Cache values to avoid duplicated sloads
    110
        bool isTopLevelCall = !$._initializing;
    111
        uint64 initialized = $._initialized;
    112
    113
        // Allowed calls:
    114
        // - initialSetup: the contract is not in the initializing state and no previous version was
    115
        //                 initialized
    116
        // - construction: the contract is initialized at version 1 (no reinitialization) and the
    117
        //                 current contract is just being deployed
    118
        bool initialSetup = initialized == 0 && isTopLevelCall;
    119
        bool construction = initialized == 1 && address(this).code.length == 0;
    120
    121
        if (!initialSetup && !construction) {
    122
          revert InvalidInitialization();
    123
        }
    124
        $._initialized = 1;
    125
        if (isTopLevelCall) {
    126
          $._initializing = true;
    127
        }
    128
        _;
    129
        if (isTopLevelCall) {
    130
          $._initializing = false;
    131
          emit Initialized(1);
    132
        }
    133
      }
    134
    135
      /**
    136
       * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
    137
       * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
    138
       * used to initialize parent contracts.
    139
       *
    140
       * A reinitializer may be used after the original initialization step. This is essential to configure modules that
    141
       * are added through upgrades and that require initialization.
    142
       *
    143
       * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
    144
       * cannot be nested. If one is invoked in the context of another, execution will revert.
    145
       *
    146
       * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
    147
       * a contract, executing them in the right order is up to the developer or operator.
    148
       *
    149
       * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.
    150
       *
    151
       * Emits an {Initialized} event.
    152
       */
    153
      modifier reinitializer(uint64 version) {
    154
        // solhint-disable-next-line var-name-mixedcase
    155
        InitializableStorage storage $ = _getInitializableStorage();
    156
    157
        if ($._initializing || $._initialized >= version) {
    158
          revert InvalidInitialization();
    159
        }
    160
        $._initialized = version;
    161
        $._initializing = true;
    162
        _;
    163
        $._initializing = false;
    164
        emit Initialized(version);
    165
      }
    166
    167
      /**
    168
       * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
    169
       * {initializer} and {reinitializer} modifiers, directly or indirectly.
    170
       */
    171
      modifier onlyInitializing() {
    172
        _checkInitializing();
    173
        _;
    174
      }
    175
    176
      /**
    177
       * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
    178
       */
    179
      function _checkInitializing() internal view virtual {
    180
        if (!_isInitializing()) {
    181
          revert NotInitializing();
    182
        }
    183
      }
    184
    185
      /**
    186
       * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
    187
       * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
    188
       * to any version. It is recommended to use this to lock implementation contracts that are designed to be called
    189
       * through proxies.
    190
       *
    191
       * Emits an {Initialized} event the first time it is successfully executed.
    192
       */
    193
      function _disableInitializers() internal virtual {
    194
        // solhint-disable-next-line var-name-mixedcase
    195
        InitializableStorage storage $ = _getInitializableStorage();
    196
    197
        if ($._initializing) {
    198
          revert InvalidInitialization();
    199
        }
    200
        if ($._initialized != type(uint64).max) {
    201
          $._initialized = type(uint64).max;
    202
          emit Initialized(type(uint64).max);
    203
        }
    204
      }
    205
    206
      /**
    207
       * @dev Returns the highest version that has been initialized. See {reinitializer}.
    208
       */
    209
      function _getInitializedVersion() internal view returns (uint64) {
    210
        return _getInitializableStorage()._initialized;
    211
      }
    212
    213
      /**
    214
       * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
    215
       */
    216
      function _isInitializing() internal view returns (bool) {
    217
        return _getInitializableStorage()._initializing;
    218
      }
    219
    220
      /**
    221
       * @dev Pointer to storage slot. Allows integrators to override it with a custom storage location.
    222
       *
    223
       * NOTE: Consider following the ERC-7201 formula to derive storage locations.
    224
       */
    225
      function _initializableStorageSlot() internal pure virtual returns (bytes32) {
    226
        return INITIALIZABLE_STORAGE;
    227
      }
    228
    229
      /**
    230
       * @dev Returns a pointer to the storage namespace.
    231
       */
    232
      // solhint-disable-next-line var-name-mixedcase
    233
      function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
    234
        bytes32 slot = _initializableStorageSlot();
    235
        assembly {
    236
          $.slot := slot
    237
        }
    238
      }
    239
    }
    240
    34.0% src/dependencies/solady/EIP712.sol
    Lines covered: 16 / 47 (34.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    pragma solidity ^0.8.4;
    3
    4
    /// @notice Contract for EIP-712 typed structured data hashing and signing.
    5
    /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/EIP712.sol)
    6
    /// @author Modified from Solbase (https://github.com/Sol-DAO/solbase/blob/main/src/utils/EIP712.sol)
    7
    /// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/EIP712.sol)
    8
    ///
    9
    /// @dev Note, this implementation:
    10
    /// - Uses `address(this)` for the `verifyingContract` field.
    11
    /// - Does NOT use the optional EIP-712 salt.
    12
    /// - Does NOT use any EIP-712 extensions.
    13
    /// This is for simplicity and to save gas.
    14
    /// If you need to customize, please fork / modify accordingly.
    15
    abstract contract EIP712 {
    16
      /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    17
      /*                  CONSTANTS AND IMMUTABLES                  */
    18
      /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
    19
    20
      /// @dev `keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")`.
    21
      bytes32 internal constant _DOMAIN_TYPEHASH =
    22
        0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;
    23
    24
      uint256 private immutable _cachedThis;
    25
      uint256 private immutable _cachedChainId;
    26
      bytes32 private immutable _cachedNameHash;
    27
      bytes32 private immutable _cachedVersionHash;
    28
      bytes32 private immutable _cachedDomainSeparator;
    29
    30
      /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    31
      /*                        CONSTRUCTOR                         */
    32
      /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
    33
    34
      /// @dev Cache the hashes for cheaper runtime gas costs.
    35
      /// In the case of upgradeable contracts (i.e. proxies),
    36
      /// or if the chain id changes due to a hard fork,
    37
      /// the domain separator will be seamlessly calculated on-the-fly.
    38
      constructor() {
    39
        _cachedThis = uint256(uint160(address(this)));
    40
        _cachedChainId = block.chainid;
    41
    42
        string memory name;
    43
        string memory version;
    44
        if (!_domainNameAndVersionMayChange()) (name, version) = _domainNameAndVersion();
    45
        bytes32 nameHash = _domainNameAndVersionMayChange() ? bytes32(0) : keccak256(bytes(name));
    46
        bytes32 versionHash = _domainNameAndVersionMayChange() ? bytes32(0) : keccak256(bytes(version));
    47
        _cachedNameHash = nameHash;
    48
        _cachedVersionHash = versionHash;
    49
    50
        bytes32 separator;
    51
        if (!_domainNameAndVersionMayChange()) {
    52
          /// @solidity memory-safe-assembly
    53
          assembly {
    54
            let m := mload(0x40) // Load the free memory pointer.
    55
            mstore(m, _DOMAIN_TYPEHASH)
    56
            mstore(add(m, 0x20), nameHash)
    57
            mstore(add(m, 0x40), versionHash)
    58
            mstore(add(m, 0x60), chainid())
    59
            mstore(add(m, 0x80), address())
    60
            separator := keccak256(m, 0xa0)
    61
          }
    62
        }
    63
        _cachedDomainSeparator = separator;
    64
      }
    65
    66
      /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    67
      /*                   FUNCTIONS TO OVERRIDE                    */
    68
      /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
    69
    70
      /// @dev Please override this function to return the domain name and version.
    71
      /// ```
    72
      ///     function _domainNameAndVersion()
    73
      ///         internal
    74
      ///         pure
    75
      ///         virtual
    76
      ///         returns (string memory name, string memory version)
    77
      ///     {
    78
      ///         name = "Solady";
    79
      ///         version = "1";
    80
      ///     }
    81
      /// ```
    82
      ///
    83
      /// Note: If the returned result may change after the contract has been deployed,
    84
      /// you must override `_domainNameAndVersionMayChange()` to return true.
    85
      function _domainNameAndVersion()
    86
        internal
    87
        view
    88
        virtual
    89
        returns (string memory name, string memory version);
    90
    91
      /// @dev Returns if `_domainNameAndVersion()` may change
    92
      /// after the contract has been deployed (i.e. after the constructor).
    93
      /// Default: false.
    94
      function _domainNameAndVersionMayChange() internal pure virtual returns (bool result) {}
    95
    96
      /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    97
      /*                     HASHING OPERATIONS                     */
    98
      /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
    99
    100
      /// @dev Returns the EIP-712 domain separator.
    101
      function _domainSeparator() internal view virtual returns (bytes32 separator) {
    102
        if (_domainNameAndVersionMayChange()) {
    103
          separator = _buildDomainSeparator();
    104
        } else {
    105
          separator = _cachedDomainSeparator;
    106
          if (_cachedDomainSeparatorInvalidated()) separator = _buildDomainSeparator();
    107
        }
    108
      }
    109
    110
      /// @dev Returns the hash of the fully encoded EIP-712 message for this domain,
    111
      /// given `structHash`, as defined in
    112
      /// https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct.
    113
      ///
    114
      /// The hash can be used together with {ECDSA-recover} to obtain the signer of a message:
    115
      /// ```
    116
      ///     bytes32 digest = _hashTypedData(keccak256(abi.encode(
    117
      ///         keccak256("Mail(address to,string contents)"),
    118
      ///         mailTo,
    119
      ///         keccak256(bytes(mailContents))
    120
      ///     )));
    121
      ///     address signer = ECDSA.recover(digest, signature);
    122
      /// ```
    123
      function _hashTypedData(bytes32 structHash) internal view virtual returns (bytes32 digest) {
    124
        // We will use `digest` to store the domain separator to save a bit of gas.
    125
        if (_domainNameAndVersionMayChange()) {
    126
          digest = _buildDomainSeparator();
    127
        } else {
    128
          digest = _cachedDomainSeparator;
    129
          if (_cachedDomainSeparatorInvalidated()) digest = _buildDomainSeparator();
    130
        }
    131
        /// @solidity memory-safe-assembly
    132
        assembly {
    133
          // Compute the digest.
    134
          mstore(0x00, 0x1901000000000000) // Store "\x19\x01".
    135
          mstore(0x1a, digest) // Store the domain separator.
    136
          mstore(0x3a, structHash) // Store the struct hash.
    137
          digest := keccak256(0x18, 0x42)
    138
          // Restore the part of the free memory slot that was overwritten.
    139
          mstore(0x3a, 0)
    140
        }
    141
      }
    142
    143
      /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    144
      /*                    EIP-5267 OPERATIONS                     */
    145
      /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
    146
    147
      /// @dev See: https://eips.ethereum.org/EIPS/eip-5267
    148
      function eip712Domain()
    149
        public
    150
        view
    151
        virtual
    152
        returns (
    153
          bytes1 fields,
    154
          string memory name,
    155
          string memory version,
    156
          uint256 chainId,
    157
          address verifyingContract,
    158
          bytes32 salt,
    159
          uint256[] memory extensions
    160
        )
    161
      {
    162
        fields = hex'0f'; // `0b01111`.
    163
        (name, version) = _domainNameAndVersion();
    164
        chainId = block.chainid;
    165
        verifyingContract = address(this);
    166
        salt = salt; // `bytes32(0)`.
    167
        extensions = extensions; // `new uint256[](0)`.
    168
      }
    169
    170
      /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    171
      /*                      PRIVATE HELPERS                       */
    172
      /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
    173
    174
      /// @dev Returns the EIP-712 domain separator.
    175
      function _buildDomainSeparator() private view returns (bytes32 separator) {
    176
        // We will use `separator` to store the name hash to save a bit of gas.
    177
        bytes32 versionHash;
    178
        if (_domainNameAndVersionMayChange()) {
    179
          (string memory name, string memory version) = _domainNameAndVersion();
    180
          separator = keccak256(bytes(name));
    181
          versionHash = keccak256(bytes(version));
    182
        } else {
    183
          separator = _cachedNameHash;
    184
          versionHash = _cachedVersionHash;
    185
        }
    186
        /// @solidity memory-safe-assembly
    187
        assembly {
    188
          let m := mload(0x40) // Load the free memory pointer.
    189
          mstore(m, _DOMAIN_TYPEHASH)
    190
          mstore(add(m, 0x20), separator) // Name hash.
    191
          mstore(add(m, 0x40), versionHash)
    192
          mstore(add(m, 0x60), chainid())
    193
          mstore(add(m, 0x80), address())
    194
          separator := keccak256(m, 0xa0)
    195
        }
    196
      }
    197
    198
      /// @dev Returns if the cached domain separator has been invalidated.
    199
      function _cachedDomainSeparatorInvalidated() private view returns (bool result) {
    200
        uint256 cachedChainId = _cachedChainId;
    201
        uint256 cachedThis = _cachedThis;
    202
        /// @solidity memory-safe-assembly
    203
        assembly {
    204
          result := iszero(and(eq(chainid(), cachedChainId), eq(address(), cachedThis)))
    205
        }
    206
      }
    207
    }
    208
    100.0% src/dependencies/solady/LibBit.sol
    Lines covered: 17 / 17 (100.0%)
    1
    // SPDX-License-Identifier: MIT
    2
    pragma solidity ^0.8.4;
    3
    4
    // trimmed https://github.com/Vectorized/solady/blob/ba711c9fa6a2dc7b2b7707f7fe136b5133379c03/src/utils/LibBit.sol
    5
    6
    /// @notice Library for bit twiddling and boolean operations.
    7
    /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibBit.sol)
    8
    /// @author Inspired by (https://graphics.stanford.edu/~seander/bithacks.html)
    9
    library LibBit {
    10
      /// @dev Returns the number of set bits in `x`.
    11
      function popCount(uint256 x) internal pure returns (uint256 c) {
    12
        /// @solidity memory-safe-assembly
    13
        assembly {
    14
          let max := not(0)
    15
          let isMax := eq(x, max)
    16
          x := sub(x, and(shr(1, x), div(max, 3)))
    17
          x := add(and(x, div(max, 5)), and(shr(2, x), div(max, 5)))
    18
          x := and(add(x, shr(4, x)), div(max, 17))
    19
          c := or(shl(8, isMax), shr(248, mul(x, div(max, 255))))
    20
        }
    21
      }
    22
    23
      /// @dev Find last set.
    24
      /// Returns the index of the most significant bit of `x`,
    25
      /// counting from the least significant bit position.
    26
      /// If `x` is zero, returns 256.
    27
      function fls(uint256 x) internal pure returns (uint256 r) {
    28
        /// @solidity memory-safe-assembly
    29
        assembly {
    30
          r := or(shl(8, iszero(x)), shl(7, lt(0xffffffffffffffffffffffffffffffff, x)))
    31
          r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
    32
          r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
    33
          r := or(r, shl(4, lt(0xffff, shr(r, x))))
    34
          r := or(r, shl(3, lt(0xff, shr(r, x))))
    35
          // forgefmt: disable-next-item
    36
          r := or(
    37
            r,
    38
            byte(
    39
              and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)),
    40
              0x0706060506020504060203020504030106050205030304010505030400000000
    41
            )
    42
          )
    43
        }
    44
      }
    45
    }
    46
    78.0% src/dependencies/weth/WETH9.sol
    Lines covered: 25 / 32 (78.0%)
    1
    // Copyright (C) 2015, 2016, 2017 Dapphub
    2
    3
    // This program is free software: you can redistribute it and/or modify
    4
    // it under the terms of the GNU General Public License as published by
    5
    // the Free Software Foundation, either version 3 of the License, or
    6
    // (at your option) any later version.
    7
    8
    // This program is distributed in the hope that it will be useful,
    9
    // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10
    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11
    // GNU General Public License for more details.
    12
    13
    // You should have received a copy of the GNU General Public License
    14
    // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15
    16
    pragma solidity ^0.8.20;
    17
    18
    contract WETH9 {
    19
      string public name = 'Wrapped Ether';
    20
      string public symbol = 'WETH';
    21
      uint8 public decimals = 18;
    22
    23
      event Approval(address indexed src, address indexed guy, uint256 wad);
    24
      event Transfer(address indexed src, address indexed dst, uint256 wad);
    25
      event Deposit(address indexed dst, uint256 wad);
    26
      event Withdrawal(address indexed src, uint256 wad);
    27
    28
      mapping(address => uint256) public balanceOf;
    29
      mapping(address => mapping(address => uint256)) public allowance;
    30
    31
      error InsufficientBalance();
    32
      error InsufficientAllowance();
    33
    34
      receive() external payable {
    35
        deposit();
    36
      }
    37
    38
      function deposit() public payable {
    39
        balanceOf[msg.sender] += msg.value;
    40
        emit Deposit(msg.sender, msg.value);
    41
      }
    42
    43
      function withdraw(uint256 wad) public {
    44
        require(balanceOf[msg.sender] >= wad);
    45
        balanceOf[msg.sender] -= wad;
    46
        payable(msg.sender).transfer(wad);
    47
        emit Withdrawal(msg.sender, wad);
    48
      }
    49
    50
      function totalSupply() public view returns (uint256) {
    51
        return address(this).balance;
    52
      }
    53
    54
      function approve(address guy, uint256 wad) public returns (bool) {
    55
        allowance[msg.sender][guy] = wad;
    56
        emit Approval(msg.sender, guy, wad);
    57
        return true;
    58
      }
    59
    60
      function transfer(address dst, uint256 wad) public returns (bool) {
    61
        return transferFrom(msg.sender, dst, wad);
    62
      }
    63
    64
      function transferFrom(address src, address dst, uint256 wad) public returns (bool) {
    65
        require(balanceOf[src] >= wad, InsufficientBalance());
    66
    67
        if (src != msg.sender && allowance[src][msg.sender] != type(uint256).max) {
    68
          require(allowance[src][msg.sender] >= wad, InsufficientAllowance());
    69
          allowance[src][msg.sender] -= wad;
    70
        }
    71
    72
        balanceOf[src] -= wad;
    73
        balanceOf[dst] += wad;
    74
    75
        emit Transfer(src, dst, wad);
    76
    77
        return true;
    78
      }
    79
    }
    80
    81
    /*
    82
                        GNU GENERAL PUBLIC LICENSE
    83
                           Version 3, 29 June 2007
    84
    85
     Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
    86
     Everyone is permitted to copy and distribute verbatim copies
    87
     of this license document, but changing it is not allowed.
    88
    89
                                Preamble
    90
    91
      The GNU General Public License is a free, copyleft license for
    92
    software and other kinds of works.
    93
    94
      The licenses for most software and other practical works are designed
    95
    to take away your freedom to share and change the works.  By contrast,
    96
    the GNU General Public License is intended to guarantee your freedom to
    97
    share and change all versions of a program--to make sure it remains free
    98
    software for all its users.  We, the Free Software Foundation, use the
    99
    GNU General Public License for most of our software; it applies also to
    100
    any other work released this way by its authors.  You can apply it to
    101
    your programs, too.
    102
    103
      When we speak of free software, we are referring to freedom, not
    104
    price.  Our General Public Licenses are designed to make sure that you
    105
    have the freedom to distribute copies of free software (and charge for
    106
    them if you wish), that you receive source code or can get it if you
    107
    want it, that you can change the software or use pieces of it in new
    108
    free programs, and that you know you can do these things.
    109
    110
      To protect your rights, we need to prevent others from denying you
    111
    these rights or asking you to surrender the rights.  Therefore, you have
    112
    certain responsibilities if you distribute copies of the software, or if
    113
    you modify it: responsibilities to respect the freedom of others.
    114
    115
      For example, if you distribute copies of such a program, whether
    116
    gratis or for a fee, you must pass on to the recipients the same
    117
    freedoms that you received.  You must make sure that they, too, receive
    118
    or can get the source code.  And you must show them these terms so they
    119
    know their rights.
    120
    121
      Developers that use the GNU GPL protect your rights with two steps:
    122
    (1) assert copyright on the software, and (2) offer you this License
    123
    giving you legal permission to copy, distribute and/or modify it.
    124
    125
      For the developers' and authors' protection, the GPL clearly explains
    126
    that there is no warranty for this free software.  For both users' and
    127
    authors' sake, the GPL requires that modified versions be marked as
    128
    changed, so that their problems will not be attributed erroneously to
    129
    authors of previous versions.
    130
    131
      Some devices are designed to deny users access to install or run
    132
    modified versions of the software inside them, although the manufacturer
    133
    can do so.  This is fundamentally incompatible with the aim of
    134
    protecting users' freedom to change the software.  The systematic
    135
    pattern of such abuse occurs in the area of products for individuals to
    136
    use, which is precisely where it is most unacceptable.  Therefore, we
    137
    have designed this version of the GPL to prohibit the practice for those
    138
    products.  If such problems arise substantially in other domains, we
    139
    stand ready to extend this provision to those domains in future versions
    140
    of the GPL, as needed to protect the freedom of users.
    141
    142
      Finally, every program is threatened constantly by software patents.
    143
    States should not allow patents to restrict development and use of
    144
    software on general-purpose computers, but in those that do, we wish to
    145
    avoid the special danger that patents applied to a free program could
    146
    make it effectively proprietary.  To prevent this, the GPL assures that
    147
    patents cannot be used to render the program non-free.
    148
    149
      The precise terms and conditions for copying, distribution and
    150
    modification follow.
    151
    152
                           TERMS AND CONDITIONS
    153
    154
      0. Definitions.
    155
    156
      "This License" refers to version 3 of the GNU General Public License.
    157
    158
      "Copyright" also means copyright-like laws that apply to other kinds of
    159
    works, such as semiconductor masks.
    160
    161
      "The Program" refers to any copyrightable work licensed under this
    162
    License.  Each licensee is addressed as "you".  "Licensees" and
    163
    "recipients" may be individuals or organizations.
    164
    165
      To "modify" a work means to copy from or adapt all or part of the work
    166
    in a fashion requiring copyright permission, other than the making of an
    167
    exact copy.  The resulting work is called a "modified version" of the
    168
    earlier work or a work "based on" the earlier work.
    169
    170
      A "covered work" means either the unmodified Program or a work based
    171
    on the Program.
    172
    173
      To "propagate" a work means to do anything with it that, without
    174
    permission, would make you directly or secondarily liable for
    175
    infringement under applicable copyright law, except executing it on a
    176
    computer or modifying a private copy.  Propagation includes copying,
    177
    distribution (with or without modification), making available to the
    178
    public, and in some countries other activities as well.
    179
    180
      To "convey" a work means any kind of propagation that enables other
    181
    parties to make or receive copies.  Mere interaction with a user through
    182
    a computer network, with no transfer of a copy, is not conveying.
    183
    184
      An interactive user interface displays "Appropriate Legal Notices"
    185
    to the extent that it includes a convenient and prominently visible
    186
    feature that (1) displays an appropriate copyright notice, and (2)
    187
    tells the user that there is no warranty for the work (except to the
    188
    extent that warranties are provided), that licensees may convey the
    189
    work under this License, and how to view a copy of this License.  If
    190
    the interface presents a list of user commands or options, such as a
    191
    menu, a prominent item in the list meets this criterion.
    192
    193
      1. Source Code.
    194
    195
      The "source code" for a work means the preferred form of the work
    196
    for making modifications to it.  "Object code" means any non-source
    197
    form of a work.
    198
    199
      A "Standard Interface" means an interface that either is an official
    200
    standard defined by a recognized standards body, or, in the case of
    201
    interfaces specified for a particular programming language, one that
    202
    is widely used among developers working in that language.
    203
    204
      The "System Libraries" of an executable work include anything, other
    205
    than the work as a whole, that (a) is included in the normal form of
    206
    packaging a Major Component, but which is not part of that Major
    207
    Component, and (b) serves only to enable use of the work with that
    208
    Major Component, or to implement a Standard Interface for which an
    209
    implementation is available to the public in source code form.  A
    210
    "Major Component", in this context, means a major essential component
    211
    (kernel, window system, and so on) of the specific operating system
    212
    (if any) on which the executable work runs, or a compiler used to
    213
    produce the work, or an object code interpreter used to run it.
    214
    215
      The "Corresponding Source" for a work in object code form means all
    216
    the source code needed to generate, install, and (for an executable
    217
    work) run the object code and to modify the work, including scripts to
    218
    control those activities.  However, it does not include the work's
    219
    System Libraries, or general-purpose tools or generally available free
    220
    programs which are used unmodified in performing those activities but
    221
    which are not part of the work.  For example, Corresponding Source
    222
    includes interface definition files associated with source files for
    223
    the work, and the source code for shared libraries and dynamically
    224
    linked subprograms that the work is specifically designed to require,
    225
    such as by intimate data communication or control flow between those
    226
    subprograms and other parts of the work.
    227
    228
      The Corresponding Source need not include anything that users
    229
    can regenerate automatically from other parts of the Corresponding
    230
    Source.
    231
    232
      The Corresponding Source for a work in source code form is that
    233
    same work.
    234
    235
      2. Basic Permissions.
    236
    237
      All rights granted under this License are granted for the term of
    238
    copyright on the Program, and are irrevocable provided the stated
    239
    conditions are met.  This License explicitly affirms your unlimited
    240
    permission to run the unmodified Program.  The output from running a
    241
    covered work is covered by this License only if the output, given its
    242
    content, constitutes a covered work.  This License acknowledges your
    243
    rights of fair use or other equivalent, as provided by copyright law.
    244
    245
      You may make, run and propagate covered works that you do not
    246
    convey, without conditions so long as your license otherwise remains
    247
    in force.  You may convey covered works to others for the sole purpose
    248
    of having them make modifications exclusively for you, or provide you
    249
    with facilities for running those works, provided that you comply with
    250
    the terms of this License in conveying all material for which you do
    251
    not control copyright.  Those thus making or running the covered works
    252
    for you must do so exclusively on your behalf, under your direction
    253
    and control, on terms that prohibit them from making any copies of
    254
    your copyrighted material outside their relationship with you.
    255
    256
      Conveying under any other circumstances is permitted solely under
    257
    the conditions stated below.  Sublicensing is not allowed; section 10
    258
    makes it unnecessary.
    259
    260
      3. Protecting Users' Legal Rights From Anti-Circumvention Law.
    261
    262
      No covered work shall be deemed part of an effective technological
    263
    measure under any applicable law fulfilling obligations under article
    264
    11 of the WIPO copyright treaty adopted on 20 December 1996, or
    265
    similar laws prohibiting or restricting circumvention of such
    266
    measures.
    267
    268
      When you convey a covered work, you waive any legal power to forbid
    269
    circumvention of technological measures to the extent such circumvention
    270
    is effected by exercising rights under this License with respect to
    271
    the covered work, and you disclaim any intention to limit operation or
    272
    modification of the work as a means of enforcing, against the work's
    273
    users, your or third parties' legal rights to forbid circumvention of
    274
    technological measures.
    275
    276
      4. Conveying Verbatim Copies.
    277
    278
      You may convey verbatim copies of the Program's source code as you
    279
    receive it, in any medium, provided that you conspicuously and
    280
    appropriately publish on each copy an appropriate copyright notice;
    281
    keep intact all notices stating that this License and any
    282
    non-permissive terms added in accord with section 7 apply to the code;
    283
    keep intact all notices of the absence of any warranty; and give all
    284
    recipients a copy of this License along with the Program.
    285
    286
      You may charge any price or no price for each copy that you convey,
    287
    and you may offer support or warranty protection for a fee.
    288
    289
      5. Conveying Modified Source Versions.
    290
    291
      You may convey a work based on the Program, or the modifications to
    292
    produce it from the Program, in the form of source code under the
    293
    terms of section 4, provided that you also meet all of these conditions:
    294
    295
        a) The work must carry prominent notices stating that you modified
    296
        it, and giving a relevant date.
    297
    298
        b) The work must carry prominent notices stating that it is
    299
        released under this License and any conditions added under section
    300
        7.  This requirement modifies the requirement in section 4 to
    301
        "keep intact all notices".
    302
    303
        c) You must license the entire work, as a whole, under this
    304
        License to anyone who comes into possession of a copy.  This
    305
        License will therefore apply, along with any applicable section 7
    306
        additional terms, to the whole of the work, and all its parts,
    307
        regardless of how they are packaged.  This License gives no
    308
        permission to license the work in any other way, but it does not
    309
        invalidate such permission if you have separately received it.
    310
    311
        d) If the work has interactive user interfaces, each must display
    312
        Appropriate Legal Notices; however, if the Program has interactive
    313
        interfaces that do not display Appropriate Legal Notices, your
    314
        work need not make them do so.
    315
    316
      A compilation of a covered work with other separate and independent
    317
    works, which are not by their nature extensions of the covered work,
    318
    and which are not combined with it such as to form a larger program,
    319
    in or on a volume of a storage or distribution medium, is called an
    320
    "aggregate" if the compilation and its resulting copyright are not
    321
    used to limit the access or legal rights of the compilation's users
    322
    beyond what the individual works permit.  Inclusion of a covered work
    323
    in an aggregate does not cause this License to apply to the other
    324
    parts of the aggregate.
    325
    326
      6. Conveying Non-Source Forms.
    327
    328
      You may convey a covered work in object code form under the terms
    329
    of sections 4 and 5, provided that you also convey the
    330
    machine-readable Corresponding Source under the terms of this License,
    331
    in one of these ways:
    332
    333
        a) Convey the object code in, or embodied in, a physical product
    334
        (including a physical distribution medium), accompanied by the
    335
        Corresponding Source fixed on a durable physical medium
    336
        customarily used for software interchange.
    337
    338
        b) Convey the object code in, or embodied in, a physical product
    339
        (including a physical distribution medium), accompanied by a
    340
        written offer, valid for at least three years and valid for as
    341
        long as you offer spare parts or customer support for that product
    342
        model, to give anyone who possesses the object code either (1) a
    343
        copy of the Corresponding Source for all the software in the
    344
        product that is covered by this License, on a durable physical
    345
        medium customarily used for software interchange, for a price no
    346
        more than your reasonable cost of physically performing this
    347
        conveying of source, or (2) access to copy the
    348
        Corresponding Source from a network server at no charge.
    349
    350
        c) Convey individual copies of the object code with a copy of the
    351
        written offer to provide the Corresponding Source.  This
    352
        alternative is allowed only occasionally and noncommercially, and
    353
        only if you received the object code with such an offer, in accord
    354
        with subsection 6b.
    355
    356
        d) Convey the object code by offering access from a designated
    357
        place (gratis or for a charge), and offer equivalent access to the
    358
        Corresponding Source in the same way through the same place at no
    359
        further charge.  You need not require recipients to copy the
    360
        Corresponding Source along with the object code.  If the place to
    361
        copy the object code is a network server, the Corresponding Source
    362
        may be on a different server (operated by you or a third party)
    363
        that supports equivalent copying facilities, provided you maintain
    364
        clear directions next to the object code saying where to find the
    365
        Corresponding Source.  Regardless of what server hosts the
    366
        Corresponding Source, you remain obligated to ensure that it is
    367
        available for as long as needed to satisfy these requirements.
    368
    369
        e) Convey the object code using peer-to-peer transmission, provided
    370
        you inform other peers where the object code and Corresponding
    371
        Source of the work are being offered to the general public at no
    372
        charge under subsection 6d.
    373
    374
      A separable portion of the object code, whose source code is excluded
    375
    from the Corresponding Source as a System Library, need not be
    376
    included in conveying the object code work.
    377
    378
      A "User Product" is either (1) a "consumer product", which means any
    379
    tangible personal property which is normally used for personal, family,
    380
    or household purposes, or (2) anything designed or sold for incorporation
    381
    into a dwelling.  In determining whether a product is a consumer product,
    382
    doubtful cases shall be resolved in favor of coverage.  For a particular
    383
    product received by a particular user, "normally used" refers to a
    384
    typical or common use of that class of product, regardless of the status
    385
    of the particular user or of the way in which the particular user
    386
    actually uses, or expects or is expected to use, the product.  A product
    387
    is a consumer product regardless of whether the product has substantial
    388
    commercial, industrial or non-consumer uses, unless such uses represent
    389
    the only significant mode of use of the product.
    390
    391
      "Installation Information" for a User Product means any methods,
    392
    procedures, authorization keys, or other information required to install
    393
    and execute modified versions of a covered work in that User Product from
    394
    a modified version of its Corresponding Source.  The information must
    395
    suffice to ensure that the continued functioning of the modified object
    396
    code is in no case prevented or interfered with solely because
    397
    modification has been made.
    398
    399
      If you convey an object code work under this section in, or with, or
    400
    specifically for use in, a User Product, and the conveying occurs as
    401
    part of a transaction in which the right of possession and use of the
    402
    User Product is transferred to the recipient in perpetuity or for a
    403
    fixed term (regardless of how the transaction is characterized), the
    404
    Corresponding Source conveyed under this section must be accompanied
    405
    by the Installation Information.  But this requirement does not apply
    406
    if neither you nor any third party retains the ability to install
    407
    modified object code on the User Product (for example, the work has
    408
    been installed in ROM).
    409
    410
      The requirement to provide Installation Information does not include a
    411
    requirement to continue to provide support service, warranty, or updates
    412
    for a work that has been modified or installed by the recipient, or for
    413
    the User Product in which it has been modified or installed.  Access to a
    414
    network may be denied when the modification itself materially and
    415
    adversely affects the operation of the network or violates the rules and
    416
    protocols for communication across the network.
    417
    418
      Corresponding Source conveyed, and Installation Information provided,
    419
    in accord with this section must be in a format that is publicly
    420
    documented (and with an implementation available to the public in
    421
    source code form), and must require no special password or key for
    422
    unpacking, reading or copying.
    423
    424
      7. Additional Terms.
    425
    426
      "Additional permissions" are terms that supplement the terms of this
    427
    License by making exceptions from one or more of its conditions.
    428
    Additional permissions that are applicable to the entire Program shall
    429
    be treated as though they were included in this License, to the extent
    430
    that they are valid under applicable law.  If additional permissions
    431
    apply only to part of the Program, that part may be used separately
    432
    under those permissions, but the entire Program remains governed by
    433
    this License without regard to the additional permissions.
    434
    435
      When you convey a copy of a covered work, you may at your option
    436
    remove any additional permissions from that copy, or from any part of
    437
    it.  (Additional permissions may be written to require their own
    438
    removal in certain cases when you modify the work.)  You may place
    439
    additional permissions on material, added by you to a covered work,
    440
    for which you have or can give appropriate copyright permission.
    441
    442
      Notwithstanding any other provision of this License, for material you
    443
    add to a covered work, you may (if authorized by the copyright holders of
    444
    that material) supplement the terms of this License with terms:
    445
    446
        a) Disclaiming warranty or limiting liability differently from the
    447
        terms of sections 15 and 16 of this License; or
    448
    449
        b) Requiring preservation of specified reasonable legal notices or
    450
        author attributions in that material or in the Appropriate Legal
    451
        Notices displayed by works containing it; or
    452
    453
        c) Prohibiting misrepresentation of the origin of that material, or
    454
        requiring that modified versions of such material be marked in
    455
        reasonable ways as different from the original version; or
    456
    457
        d) Limiting the use for publicity purposes of names of licensors or
    458
        authors of the material; or
    459
    460
        e) Declining to grant rights under trademark law for use of some
    461
        trade names, trademarks, or service marks; or
    462
    463
        f) Requiring indemnification of licensors and authors of that
    464
        material by anyone who conveys the material (or modified versions of
    465
        it) with contractual assumptions of liability to the recipient, for
    466
        any liability that these contractual assumptions directly impose on
    467
        those licensors and authors.
    468
    469
      All other non-permissive additional terms are considered "further
    470
    restrictions" within the meaning of section 10.  If the Program as you
    471
    received it, or any part of it, contains a notice stating that it is
    472
    governed by this License along with a term that is a further
    473
    restriction, you may remove that term.  If a license document contains
    474
    a further restriction but permits relicensing or conveying under this
    475
    License, you may add to a covered work material governed by the terms
    476
    of that license document, provided that the further restriction does
    477
    not survive such relicensing or conveying.
    478
    479
      If you add terms to a covered work in accord with this section, you
    480
    must place, in the relevant source files, a statement of the
    481
    additional terms that apply to those files, or a notice indicating
    482
    where to find the applicable terms.
    483
    484
      Additional terms, permissive or non-permissive, may be stated in the
    485
    form of a separately written license, or stated as exceptions;
    486
    the above requirements apply either way.
    487
    488
      8. Termination.
    489
    490
      You may not propagate or modify a covered work except as expressly
    491
    provided under this License.  Any attempt otherwise to propagate or
    492
    modify it is void, and will automatically terminate your rights under
    493
    this License (including any patent licenses granted under the third
    494
    paragraph of section 11).
    495
    496
      However, if you cease all violation of this License, then your
    497
    license from a particular copyright holder is reinstated (a)
    498
    provisionally, unless and until the copyright holder explicitly and
    499
    finally terminates your license, and (b) permanently, if the copyright
    500
    holder fails to notify you of the violation by some reasonable means
    501
    prior to 60 days after the cessation.
    502
    503
      Moreover, your license from a particular copyright holder is
    504
    reinstated permanently if the copyright holder notifies you of the
    505
    violation by some reasonable means, this is the first time you have
    506
    received notice of violation of this License (for any work) from that
    507
    copyright holder, and you cure the violation prior to 30 days after
    508
    your receipt of the notice.
    509
    510
      Termination of your rights under this section does not terminate the
    511
    licenses of parties who have received copies or rights from you under
    512
    this License.  If your rights have been terminated and not permanently
    513
    reinstated, you do not qualify to receive new licenses for the same
    514
    material under section 10.
    515
    516
      9. Acceptance Not Required for Having Copies.
    517
    518
      You are not required to accept this License in order to receive or
    519
    run a copy of the Program.  Ancillary propagation of a covered work
    520
    occurring solely as a consequence of using peer-to-peer transmission
    521
    to receive a copy likewise does not require acceptance.  However,
    522
    nothing other than this License grants you permission to propagate or
    523
    modify any covered work.  These actions infringe copyright if you do
    524
    not accept this License.  Therefore, by modifying or propagating a
    525
    covered work, you indicate your acceptance of this License to do so.
    526
    527
      10. Automatic Licensing of Downstream Recipients.
    528
    529
      Each time you convey a covered work, the recipient automatically
    530
    receives a license from the original licensors, to run, modify and
    531
    propagate that work, subject to this License.  You are not responsible
    532
    for enforcing compliance by third parties with this License.
    533
    534
      An "entity transaction" is a transaction transferring control of an
    535
    organization, or substantially all assets of one, or subdividing an
    536
    organization, or merging organizations.  If propagation of a covered
    537
    work results from an entity transaction, each party to that
    538
    transaction who receives a copy of the work also receives whatever
    539
    licenses to the work the party's predecessor in interest had or could
    540
    give under the previous paragraph, plus a right to possession of the
    541
    Corresponding Source of the work from the predecessor in interest, if
    542
    the predecessor has it or can get it with reasonable efforts.
    543
    544
      You may not impose any further restrictions on the exercise of the
    545
    rights granted or affirmed under this License.  For example, you may
    546
    not impose a license fee, royalty, or other charge for exercise of
    547
    rights granted under this License, and you may not initiate litigation
    548
    (including a cross-claim or counterclaim in a lawsuit) alleging that
    549
    any patent claim is infringed by making, using, selling, offering for
    550
    sale, or importing the Program or any portion of it.
    551
    552
      11. Patents.
    553
    554
      A "contributor" is a copyright holder who authorizes use under this
    555
    License of the Program or a work on which the Program is based.  The
    556
    work thus licensed is called the contributor's "contributor version".
    557
    558
      A contributor's "essential patent claims" are all patent claims
    559
    owned or controlled by the contributor, whether already acquired or
    560
    hereafter acquired, that would be infringed by some manner, permitted
    561
    by this License, of making, using, or selling its contributor version,
    562
    but do not include claims that would be infringed only as a
    563
    consequence of further modification of the contributor version.  For
    564
    purposes of this definition, "control" includes the right to grant
    565
    patent sublicenses in a manner consistent with the requirements of
    566
    this License.
    567
    568
      Each contributor grants you a non-exclusive, worldwide, royalty-free
    569
    patent license under the contributor's essential patent claims, to
    570
    make, use, sell, offer for sale, import and otherwise run, modify and
    571
    propagate the contents of its contributor version.
    572
    573
      In the following three paragraphs, a "patent license" is any express
    574
    agreement or commitment, however denominated, not to enforce a patent
    575
    (such as an express permission to practice a patent or covenant not to
    576
    sue for patent infringement).  To "grant" such a patent license to a
    577
    party means to make such an agreement or commitment not to enforce a
    578
    patent against the party.
    579
    580
      If you convey a covered work, knowingly relying on a patent license,
    581
    and the Corresponding Source of the work is not available for anyone
    582
    to copy, free of charge and under the terms of this License, through a
    583
    publicly available network server or other readily accessible means,
    584
    then you must either (1) cause the Corresponding Source to be so
    585
    available, or (2) arrange to deprive yourself of the benefit of the
    586
    patent license for this particular work, or (3) arrange, in a manner
    587
    consistent with the requirements of this License, to extend the patent
    588
    license to downstream recipients.  "Knowingly relying" means you have
    589
    actual knowledge that, but for the patent license, your conveying the
    590
    covered work in a country, or your recipient's use of the covered work
    591
    in a country, would infringe one or more identifiable patents in that
    592
    country that you have reason to believe are valid.
    593
    594
      If, pursuant to or in connection with a single transaction or
    595
    arrangement, you convey, or propagate by procuring conveyance of, a
    596
    covered work, and grant a patent license to some of the parties
    597
    receiving the covered work authorizing them to use, propagate, modify
    598
    or convey a specific copy of the covered work, then the patent license
    599
    you grant is automatically extended to all recipients of the covered
    600
    work and works based on it.
    601
    602
      A patent license is "discriminatory" if it does not include within
    603
    the scope of its coverage, prohibits the exercise of, or is
    604
    conditioned on the non-exercise of one or more of the rights that are
    605
    specifically granted under this License.  You may not convey a covered
    606
    work if you are a party to an arrangement with a third party that is
    607
    in the business of distributing software, under which you make payment
    608
    to the third party based on the extent of your activity of conveying
    609
    the work, and under which the third party grants, to any of the
    610
    parties who would receive the covered work from you, a discriminatory
    611
    patent license (a) in connection with copies of the covered work
    612
    conveyed by you (or copies made from those copies), or (b) primarily
    613
    for and in connection with specific products or compilations that
    614
    contain the covered work, unless you entered into that arrangement,
    615
    or that patent license was granted, prior to 28 March 2007.
    616
    617
      Nothing in this License shall be construed as excluding or limiting
    618
    any implied license or other defenses to infringement that may
    619
    otherwise be available to you under applicable patent law.
    620
    621
      12. No Surrender of Others' Freedom.
    622
    623
      If conditions are imposed on you (whether by court order, agreement or
    624
    otherwise) that contradict the conditions of this License, they do not
    625
    excuse you from the conditions of this License.  If you cannot convey a
    626
    covered work so as to satisfy simultaneously your obligations under this
    627
    License and any other pertinent obligations, then as a consequence you may
    628
    not convey it at all.  For example, if you agree to terms that obligate you
    629
    to collect a royalty for further conveying from those to whom you convey
    630
    the Program, the only way you could satisfy both those terms and this
    631
    License would be to refrain entirely from conveying the Program.
    632
    633
      13. Use with the GNU Affero General Public License.
    634
    635
      Notwithstanding any other provision of this License, you have
    636
    permission to link or combine any covered work with a work licensed
    637
    under version 3 of the GNU Affero General Public License into a single
    638
    combined work, and to convey the resulting work.  The terms of this
    639
    License will continue to apply to the part which is the covered work,
    640
    but the special requirements of the GNU Affero General Public License,
    641
    section 13, concerning interaction through a network will apply to the
    642
    combination as such.
    643
    644
      14. Revised Versions of this License.
    645
    646
      The Free Software Foundation may publish revised and/or new versions of
    647
    the GNU General Public License from time to time.  Such new versions will
    648
    be similar in spirit to the present version, but may differ in detail to
    649
    address new problems or concerns.
    650
    651
      Each version is given a distinguishing version number.  If the
    652
    Program specifies that a certain numbered version of the GNU General
    653
    Public License "or any later version" applies to it, you have the
    654
    option of following the terms and conditions either of that numbered
    655
    version or of any later version published by the Free Software
    656
    Foundation.  If the Program does not specify a version number of the
    657
    GNU General Public License, you may choose any version ever published
    658
    by the Free Software Foundation.
    659
    660
      If the Program specifies that a proxy can decide which future
    661
    versions of the GNU General Public License can be used, that proxy's
    662
    public statement of acceptance of a version permanently authorizes you
    663
    to choose that version for the Program.
    664
    665
      Later license versions may give you additional or different
    666
    permissions.  However, no additional obligations are imposed on any
    667
    author or copyright holder as a result of your choosing to follow a
    668
    later version.
    669
    670
      15. Disclaimer of Warranty.
    671
    672
      THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
    673
    APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
    674
    HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
    675
    OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
    676
    THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    677
    PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
    678
    IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
    679
    ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
    680
    681
      16. Limitation of Liability.
    682
    683
      IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
    684
    WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
    685
    THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
    686
    GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
    687
    USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
    688
    DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
    689
    PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
    690
    EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
    691
    SUCH DAMAGES.
    692
    693
      17. Interpretation of Sections 15 and 16.
    694
    695
      If the disclaimer of warranty and limitation of liability provided
    696
    above cannot be given local legal effect according to their terms,
    697
    reviewing courts shall apply local law that most closely approximates
    698
    an absolute waiver of all civil liability in connection with the
    699
    Program, unless a warranty or assumption of liability accompanies a
    700
    copy of the Program in return for a fee.
    701
    702
                         END OF TERMS AND CONDITIONS
    703
    704
                How to Apply These Terms to Your New Programs
    705
    706
      If you develop a new program, and you want it to be of the greatest
    707
    possible use to the public, the best way to achieve this is to make it
    708
    free software which everyone can redistribute and change under these terms.
    709
    710
      To do so, attach the following notices to the program.  It is safest
    711
    to attach them to the start of each source file to most effectively
    712
    state the exclusion of warranty; and each file should have at least
    713
    the "copyright" line and a pointer to where the full notice is found.
    714
    715
        <one line to give the program's name and a brief idea of what it does.>
    716
        Copyright (C) <year>  <name of author>
    717
    718
        This program is free software: you can redistribute it and/or modify
    719
        it under the terms of the GNU General Public License as published by
    720
        the Free Software Foundation, either version 3 of the License, or
    721
        (at your option) any later version.
    722
    723
        This program is distributed in the hope that it will be useful,
    724
        but WITHOUT ANY WARRANTY; without even the implied warranty of
    725
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    726
        GNU General Public License for more details.
    727
    728
        You should have received a copy of the GNU General Public License
    729
        along with this program.  If not, see <http://www.gnu.org/licenses/>.
    730
    731
    Also add information on how to contact you by electronic and paper mail.
    732
    733
      If the program does terminal interaction, make it output a short
    734
    notice like this when it starts in an interactive mode:
    735
    736
        <program>  Copyright (C) <year>  <name of author>
    737
        This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    738
        This is free software, and you are welcome to redistribute it
    739
        under certain conditions; type `show c' for details.
    740
    741
    The hypothetical commands `show w' and `show c' should show the appropriate
    742
    parts of the General Public License.  Of course, your program's commands
    743
    might be different; for a GUI interface, you would use an "about box".
    744
    745
      You should also get your employer (if you work as a programmer) or school,
    746
    if any, to sign a "copyright disclaimer" for the program, if necessary.
    747
    For more information on this, and how to apply and follow the GNU GPL, see
    748
    <http://www.gnu.org/licenses/>.
    749
    750
      The GNU General Public License does not permit incorporating your program
    751
    into proprietary programs.  If your program is a subroutine library, you
    752
    may consider it more useful to permit linking proprietary applications with
    753
    the library.  If this is what you want to do, use the GNU Lesser General
    754
    Public License instead of this License.  But first, please read
    755
    <http://www.gnu.org/philosophy/why-not-lgpl.html>.
    756
    757
    */
    758
    72.0% src/hub/AssetInterestRateStrategy.sol
    Lines covered: 39 / 54 (72.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity 0.8.28;
    4
    5
    import {WadRayMath} from 'src/libraries/math/WadRayMath.sol';
    6
    import {IAssetInterestRateStrategy, IBasicInterestRateStrategy} from 'src/hub/interfaces/IAssetInterestRateStrategy.sol';
    7
    8
    /// @title AssetInterestRateStrategy
    9
    /// @author Aave Labs
    10
    /// @notice Manages the kink-based interest rate strategy for an asset.
    11
    /// @dev Strategies are Hub-specific, due to the usage of asset identifier as index of the `_interestRateData` mapping.
    12
    contract AssetInterestRateStrategy is IAssetInterestRateStrategy {
    13
      using WadRayMath for *;
    14
    15
      /// @inheritdoc IAssetInterestRateStrategy
    16
      uint256 public constant MAX_BORROW_RATE = 1000_00;
    17
    18
      /// @inheritdoc IAssetInterestRateStrategy
    19
      uint256 public constant MIN_OPTIMAL_RATIO = 1_00;
    20
    21
      /// @inheritdoc IAssetInterestRateStrategy
    22
      uint256 public constant MAX_OPTIMAL_RATIO = 99_00;
    23
    24
      /// @inheritdoc IAssetInterestRateStrategy
    25
      address public immutable HUB;
    26
    27
      /// @dev Map of asset identifiers to their interest rate data.
    28
      mapping(uint256 assetId => InterestRateData) internal _interestRateData;
    29
    30
      /// @dev Constructor.
    31
      /// @param hub_ The address of the associated Hub.
    32
      constructor(address hub_) {
    33
        require(hub_ != address(0), InvalidAddress());
    34
        HUB = hub_;
    35
      }
    36
    37
      /// @notice Sets the interest rate parameters for a specified asset.
    38
      /// @param assetId The identifier of the asset.
    39
      /// @param data The encoded parameters containing BPS data used to configure the interest rate of the asset.
    40
      function setInterestRateData(uint256 assetId, bytes calldata data) external {
    41
        require(HUB == msg.sender, OnlyHub());
    42
        InterestRateData memory rateData = abi.decode(data, (InterestRateData));
    43
        require(
    44
          MIN_OPTIMAL_RATIO <= rateData.optimalUsageRatio &&
    45
            rateData.optimalUsageRatio <= MAX_OPTIMAL_RATIO,
    46
          InvalidOptimalUsageRatio()
    47
        );
    48
        require(rateData.variableRateSlope1 <= rateData.variableRateSlope2, Slope2MustBeGteSlope1());
    49
        require(
    50
          rateData.baseVariableBorrowRate + rateData.variableRateSlope1 + rateData.variableRateSlope2 <=
    51
            MAX_BORROW_RATE,
    52
          InvalidMaxRate()
    53
        );
    54
    55
        _interestRateData[assetId] = rateData;
    56
    57
        emit UpdateRateData(
    58
          HUB,
    59
          assetId,
    60
          rateData.optimalUsageRatio,
    61
          rateData.baseVariableBorrowRate,
    62
          rateData.variableRateSlope1,
    63
          rateData.variableRateSlope2
    64
        );
    65
      }
    66
    67
      /// @inheritdoc IAssetInterestRateStrategy
    68
      function getInterestRateData(uint256 assetId) external view returns (InterestRateData memory) {
    69
        return _interestRateData[assetId];
    70
      }
    71
    72
      /// @inheritdoc IAssetInterestRateStrategy
    73
      function getOptimalUsageRatio(uint256 assetId) external view returns (uint256) {
    74
        return _interestRateData[assetId].optimalUsageRatio;
    75
      }
    76
    77
      /// @inheritdoc IAssetInterestRateStrategy
    78
      function getBaseVariableBorrowRate(uint256 assetId) external view returns (uint256) {
    79
        return _interestRateData[assetId].baseVariableBorrowRate;
    80
      }
    81
    82
      /// @inheritdoc IAssetInterestRateStrategy
    83
      function getVariableRateSlope1(uint256 assetId) external view returns (uint256) {
    84
        return _interestRateData[assetId].variableRateSlope1;
    85
      }
    86
    87
      /// @inheritdoc IAssetInterestRateStrategy
    88
      function getVariableRateSlope2(uint256 assetId) external view returns (uint256) {
    89
        return _interestRateData[assetId].variableRateSlope2;
    90
      }
    91
    92
      /// @inheritdoc IAssetInterestRateStrategy
    93
      function getMaxVariableBorrowRate(uint256 assetId) external view returns (uint256) {
    94
        return
    95
          _interestRateData[assetId].baseVariableBorrowRate +
    96
          _interestRateData[assetId].variableRateSlope1 +
    97
          _interestRateData[assetId].variableRateSlope2;
    98
      }
    99
    100
      /// @inheritdoc IBasicInterestRateStrategy
    101
      function calculateInterestRate(
    102
        uint256 assetId,
    103
        uint256 liquidity,
    104
        uint256 drawn,
    105
        uint256 /* deficit */,
    106
        uint256 swept
    107
      ) external view returns (uint256) {
    108
        InterestRateData memory rateData = _interestRateData[assetId];
    109
        require(rateData.optimalUsageRatio > 0, InterestRateDataNotSet(assetId));
    110
    111
        uint256 currentVariableBorrowRateRay = rateData.baseVariableBorrowRate.bpsToRay();
    112
        if (drawn == 0) {
    113
          return currentVariableBorrowRateRay;
    114
        }
    115
    116
        uint256 usageRatioRay = drawn.rayDivUp(liquidity + drawn + swept);
    117
        uint256 optimalUsageRatioRay = rateData.optimalUsageRatio.bpsToRay();
    118
    119
        if (usageRatioRay <= optimalUsageRatioRay) {
    120
          currentVariableBorrowRateRay += rateData
    121
            .variableRateSlope1
    122
            .bpsToRay()
    123
            .rayMulUp(usageRatioRay)
    124
            .rayDivUp(optimalUsageRatioRay);
    125
        } else {
    126
          currentVariableBorrowRateRay +=
    127
            rateData.variableRateSlope1.bpsToRay() +
    128
            rateData
    129
              .variableRateSlope2
    130
              .bpsToRay()
    131
              .rayMulUp(usageRatioRay - optimalUsageRatioRay)
    132
              .rayDivUp(WadRayMath.RAY - optimalUsageRatioRay);
    133
        }
    134
    135
        return currentVariableBorrowRateRay;
    136
      }
    137
    }
    138
    61.0% src/hub/Hub.sol
    Lines covered: 296 / 478 (61.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity 0.8.28;
    4
    5
    import {EnumerableSet} from 'src/dependencies/openzeppelin/EnumerableSet.sol';
    6
    import {AccessManaged} from 'src/dependencies/openzeppelin/AccessManaged.sol';
    7
    import {SafeCast} from 'src/dependencies/openzeppelin/SafeCast.sol';
    8
    import {SafeERC20, IERC20} from 'src/dependencies/openzeppelin/SafeERC20.sol';
    9
    import {MathUtils} from 'src/libraries/math/MathUtils.sol';
    10
    import {PercentageMath} from 'src/libraries/math/PercentageMath.sol';
    11
    import {WadRayMath} from 'src/libraries/math/WadRayMath.sol';
    12
    import {AssetLogic} from 'src/hub/libraries/AssetLogic.sol';
    13
    import {SharesMath} from 'src/hub/libraries/SharesMath.sol';
    14
    import {Premium} from 'src/hub/libraries/Premium.sol';
    15
    import {IBasicInterestRateStrategy} from 'src/hub/interfaces/IBasicInterestRateStrategy.sol';
    16
    import {IHubBase, IHub} from 'src/hub/interfaces/IHub.sol';
    17
    18
    /// @title Hub
    19
    /// @author Aave Labs
    20
    /// @notice A liquidity hub that manages assets and spokes.
    21
    contract Hub is IHub, AccessManaged {
    22
      using EnumerableSet for EnumerableSet.AddressSet;
    23
      using SafeCast for *;
    24
      using SafeERC20 for IERC20;
    25
      using MathUtils for *;
    26
      using PercentageMath for *;
    27
      using WadRayMath for uint256;
    28
      using AssetLogic for Asset;
    29
      using SharesMath for uint256;
    30
    31
      /// @inheritdoc IHub
    32
      uint8 public constant MAX_ALLOWED_UNDERLYING_DECIMALS = 18;
    33
    34
      /// @inheritdoc IHub
    35
      uint8 public constant MIN_ALLOWED_UNDERLYING_DECIMALS = 6;
    36
    37
      /// @inheritdoc IHub
    38
      uint40 public constant MAX_ALLOWED_SPOKE_CAP = type(uint40).max;
    39
    40
      /// @inheritdoc IHub
    41
      uint24 public constant MAX_RISK_PREMIUM_THRESHOLD = type(uint24).max;
    42
    43
      /// @dev Number of assets listed in the Hub.
    44
      uint256 internal _assetCount;
    45
    46
      /// @dev Map of asset identifiers to Asset data.
    47
      mapping(uint256 assetId => Asset) internal _assets;
    48
    49
      /// @dev Map of asset identifiers and spoke addresses to Spoke data.
    50
      mapping(uint256 assetId => mapping(address spoke => SpokeData)) internal _spokes;
    51
    52
      /// @dev Map of asset identifiers to set of spoke addresses.
    53
      mapping(uint256 assetId => EnumerableSet.AddressSet) internal _assetToSpokes;
    54
    55
      /// @dev Set of underlying addresses listed as assets in the Hub.
    56
      EnumerableSet.AddressSet internal _underlyingAssets;
    57
    58
      /// @dev Constructor.
    59
      /// @dev The authority contract must implement the `AccessManaged` interface for access control.
    60
      /// @param authority_ The address of the authority contract which manages permissions.
    61
      constructor(address authority_) AccessManaged(authority_) {
    62
        require(authority_ != address(0), InvalidAddress());
    63
      }
    64
    65
      /// @inheritdoc IHub
    66
      function addAsset(
    67
        address underlying,
    68
        uint8 decimals,
    69
        address feeReceiver,
    70
        address irStrategy,
    71
        bytes calldata irData
    72
      ) external restricted returns (uint256) {
    73
        require(
    74
          underlying != address(0) && feeReceiver != address(0) && irStrategy != address(0),
    75
          InvalidAddress()
    76
        );
    77
        require(
    78
          MIN_ALLOWED_UNDERLYING_DECIMALS <= decimals && decimals <= MAX_ALLOWED_UNDERLYING_DECIMALS,
    79
          InvalidAssetDecimals()
    80
        );
    81
        require(!_underlyingAssets.contains(underlying), UnderlyingAlreadyListed());
    82
    83
        uint256 assetId = _assetCount++;
    84
        IBasicInterestRateStrategy(irStrategy).setInterestRateData(assetId, irData);
    85
        uint256 drawnRate = IBasicInterestRateStrategy(irStrategy).calculateInterestRate({
    86
          assetId: assetId,
    87
          liquidity: 0,
    88
          drawn: 0,
    89
          deficit: 0,
    90
          swept: 0
    91
        });
    92
    93
        uint256 drawnIndex = WadRayMath.RAY;
    94
        uint256 lastUpdateTimestamp = block.timestamp;
    95
        _assets[assetId] = Asset({
    96
          liquidity: 0,
    97
          deficitRay: 0,
    98
          swept: 0,
    99
          addedShares: 0,
    100
          drawnShares: 0,
    101
          premiumShares: 0,
    102
          premiumOffsetRay: 0,
    103
          drawnIndex: drawnIndex.toUint120(),
    104
          underlying: underlying,
    105
          lastUpdateTimestamp: lastUpdateTimestamp.toUint40(),
    106
          decimals: decimals,
    107
          drawnRate: drawnRate.toUint96(),
    108
          irStrategy: irStrategy,
    109
          realizedFees: 0,
    110
          reinvestmentController: address(0),
    111
          feeReceiver: feeReceiver,
    112
          liquidityFee: 0
    113
        });
    114
        _underlyingAssets.add(underlying);
    115
        _addFeeReceiver(assetId, feeReceiver);
    116
    117
        emit AddAsset(assetId, underlying, decimals);
    118
        emit UpdateAssetConfig(
    119
          assetId,
    120
          AssetConfig({
    121
            feeReceiver: feeReceiver,
    122
            liquidityFee: 0,
    123
            irStrategy: irStrategy,
    124
            reinvestmentController: address(0)
    125
          })
    126
        );
    127
        emit UpdateAsset(assetId, drawnIndex, drawnRate, 0);
    128
    129
        return assetId;
    130
      }
    131
    132
      /// @inheritdoc IHub
    133
      function updateAssetConfig(
    134
        uint256 assetId,
    135
        AssetConfig calldata config,
    136
        bytes calldata irData
    137
      ) external restricted {
    138
        require(assetId < _assetCount, AssetNotListed());
    139
        Asset storage asset = _assets[assetId];
    140
        asset.accrue();
    141
    142
        require(config.liquidityFee <= PercentageMath.PERCENTAGE_FACTOR, InvalidLiquidityFee());
    143
        require(config.feeReceiver != address(0) && config.irStrategy != address(0), InvalidAddress());
    144
        require(
    145
          config.reinvestmentController != address(0) || asset.swept == 0,
    146
          InvalidReinvestmentController()
    147
        );
    148
    149
        if (config.irStrategy != asset.irStrategy) {
    150
          asset.irStrategy = config.irStrategy;
    151
          IBasicInterestRateStrategy(config.irStrategy).setInterestRateData(assetId, irData);
    152
        } else {
    153
          require(irData.length == 0, InvalidInterestRateStrategy());
    154
        }
    155
    156
        address oldFeeReceiver = asset.feeReceiver;
    157
        if (oldFeeReceiver != config.feeReceiver) {
    158
          _mintFeeShares(asset, assetId);
    159
          IHub.SpokeConfig memory spokeConfig;
    160
          spokeConfig.active = _spokes[assetId][oldFeeReceiver].active;
    161
          spokeConfig.paused = _spokes[assetId][oldFeeReceiver].paused;
    162
          _updateSpokeConfig(assetId, oldFeeReceiver, spokeConfig);
    163
          asset.feeReceiver = config.feeReceiver;
    164
          _addFeeReceiver(assetId, config.feeReceiver);
    165
        }
    166
    167
        asset.liquidityFee = config.liquidityFee;
    168
        asset.reinvestmentController = config.reinvestmentController;
    169
    170
        asset.updateDrawnRate(assetId);
    171
    172
        emit UpdateAssetConfig(assetId, config);
    173
      }
    174
    175
      /// @inheritdoc IHub
    176
      function addSpoke(
    177
        uint256 assetId,
    178
        address spoke,
    179
        SpokeConfig calldata config
    180
      ) external restricted {
    181
        require(assetId < _assetCount, AssetNotListed());
    182
        require(spoke != address(0), InvalidAddress());
    183
        _addSpoke(assetId, spoke);
    184
        _updateSpokeConfig(assetId, spoke, config);
    185
      }
    186
    187
      /// @inheritdoc IHub
    188
      function updateSpokeConfig(
    189
        uint256 assetId,
    190
        address spoke,
    191
        SpokeConfig calldata config
    192
      ) external restricted {
    193
        require(assetId < _assetCount, AssetNotListed());
    194
        require(_assetToSpokes[assetId].contains(spoke), SpokeNotListed());
    195
        _updateSpokeConfig(assetId, spoke, config);
    196
      }
    197
    198
      /// @inheritdoc IHub
    199
      function setInterestRateData(uint256 assetId, bytes calldata irData) external restricted {
    200
        require(assetId < _assetCount, AssetNotListed());
    201
        Asset storage asset = _assets[assetId];
    202
        asset.accrue();
    203
        IBasicInterestRateStrategy(asset.irStrategy).setInterestRateData(assetId, irData);
    204
        asset.updateDrawnRate(assetId);
    205
      }
    206
    207
      /// @inheritdoc IHub
    208
      function mintFeeShares(uint256 assetId) external restricted returns (uint256) {
    209
        Asset storage asset = _assets[assetId];
    210
        asset.accrue();
    211
        uint256 feeShares = _mintFeeShares(asset, assetId);
    212
        asset.updateDrawnRate(assetId);
    213
        return feeShares;
    214
      }
    215
    216
      /// @inheritdoc IHubBase
    217
      function add(uint256 assetId, uint256 amount) external returns (uint256) {
    218
        Asset storage asset = _assets[assetId];
    219
        SpokeData storage spoke = _spokes[assetId][msg.sender];
    220
    221
        asset.accrue();
    222
        _validateAdd(asset, spoke, amount);
    223
    224
        uint256 liquidity = asset.liquidity + amount;
    225
        uint256 balance = IERC20(asset.underlying).balanceOf(address(this));
    226
        require(balance >= liquidity, InsufficientTransferred(liquidity.uncheckedSub(balance)));
    227
        uint120 shares = asset.toAddedSharesDown(amount).toUint120();
    228
        require(shares > 0, InvalidShares());
    229
        asset.addedShares += shares;
    230
        spoke.addedShares += shares;
    231
        asset.liquidity = liquidity.toUint120();
    232
    233
        asset.updateDrawnRate(assetId);
    234
    235
        emit Add(assetId, msg.sender, shares, amount);
    236
    237
        return shares;
    238
      }
    239
    240
      /// @inheritdoc IHubBase
    241
      function remove(uint256 assetId, uint256 amount, address to) external returns (uint256) {
    242
        Asset storage asset = _assets[assetId];
    243
        SpokeData storage spoke = _spokes[assetId][msg.sender];
    244
    245
        asset.accrue();
    246
        _validateRemove(spoke, amount, to);
    247
    248
        uint256 liquidity = asset.liquidity;
    249
        require(amount <= liquidity, InsufficientLiquidity(liquidity));
    250
    251
        uint120 shares = asset.toAddedSharesUp(amount).toUint120();
    252
        asset.addedShares -= shares;
    253
        spoke.addedShares -= shares;
    254
        asset.liquidity = liquidity.uncheckedSub(amount).toUint120();
    255
    256
        asset.updateDrawnRate(assetId);
    257
    258
        IERC20(asset.underlying).safeTransfer(to, amount);
    259
    260
        emit Remove(assetId, msg.sender, shares, amount);
    261
    262
        return shares;
    263
      }
    264
    265
      /// @inheritdoc IHubBase
    266
      function draw(uint256 assetId, uint256 amount, address to) external returns (uint256) {
    267
        Asset storage asset = _assets[assetId];
    268
        SpokeData storage spoke = _spokes[assetId][msg.sender];
    269
    270
        asset.accrue();
    271
        _validateDraw(asset, spoke, amount, to);
    272
    273
        uint256 liquidity = asset.liquidity;
    274
        require(amount <= liquidity, InsufficientLiquidity(liquidity));
    275
    276
        uint120 drawnShares = asset.toDrawnSharesUp(amount).toUint120();
    277
        asset.drawnShares += drawnShares;
    278
        spoke.drawnShares += drawnShares;
    279
        asset.liquidity = liquidity.uncheckedSub(amount).toUint120();
    280
    281
        asset.updateDrawnRate(assetId);
    282
    283
        IERC20(asset.underlying).safeTransfer(to, amount);
    284
    285
        emit Draw(assetId, msg.sender, drawnShares, amount);
    286
    287
        return drawnShares;
    288
      }
    289
    290
      /// @inheritdoc IHubBase
    291
      function restore(
    292
        uint256 assetId,
    293
        uint256 drawnAmount,
    294
        PremiumDelta calldata premiumDelta
    295
      ) external returns (uint256) {
    296
        Asset storage asset = _assets[assetId];
    297
        SpokeData storage spoke = _spokes[assetId][msg.sender];
    298
    299
        asset.accrue();
    300
        _validateRestore(asset, spoke, drawnAmount, premiumDelta.restoredPremiumRay);
    301
    302
        uint120 drawnShares = asset.toDrawnSharesDown(drawnAmount).toUint120();
    303
        asset.drawnShares -= drawnShares;
    304
        spoke.drawnShares -= drawnShares;
    305
        _applyPremiumDelta(asset, spoke, premiumDelta);
    306
    307
        uint256 premiumAmount = premiumDelta.restoredPremiumRay.fromRayUp();
    308
        uint256 liquidity = asset.liquidity + drawnAmount + premiumAmount;
    309
        uint256 balance = IERC20(asset.underlying).balanceOf(address(this));
    310
        require(balance >= liquidity, InsufficientTransferred(liquidity.uncheckedSub(balance)));
    311
        asset.liquidity = liquidity.toUint120();
    312
    313
        asset.updateDrawnRate(assetId);
    314
    315
        emit Restore(assetId, msg.sender, drawnShares, premiumDelta, drawnAmount, premiumAmount);
    316
    317
        return drawnShares;
    318
      }
    319
    320
      /// @inheritdoc IHubBase
    321
      function reportDeficit(
    322
        uint256 assetId,
    323
        uint256 drawnAmount,
    324
        PremiumDelta calldata premiumDelta
    325
      ) external returns (uint256) {
    326
        Asset storage asset = _assets[assetId];
    327
        SpokeData storage spoke = _spokes[assetId][msg.sender];
    328
    329
        asset.accrue();
    330
        _validateReportDeficit(asset, spoke, drawnAmount, premiumDelta.restoredPremiumRay);
    331
    332
        uint120 drawnShares = asset.toDrawnSharesDown(drawnAmount).toUint120();
    333
        asset.drawnShares -= drawnShares;
    334
        spoke.drawnShares -= drawnShares;
    335
        _applyPremiumDelta(asset, spoke, premiumDelta);
    336
    337
        uint256 deficitAmountRay = uint256(drawnShares) *
    338
          asset.drawnIndex +
    339
          premiumDelta.restoredPremiumRay;
    340
        asset.deficitRay += deficitAmountRay.toUint200();
    341
        spoke.deficitRay += deficitAmountRay.toUint200();
    342
    343
        asset.updateDrawnRate(assetId);
    344
    345
        emit ReportDeficit(assetId, msg.sender, drawnShares, premiumDelta, deficitAmountRay);
    346
    347
        return drawnShares;
    348
      }
    349
    350
      /// @inheritdoc IHub
    351
      function eliminateDeficit(
    352
        uint256 assetId,
    353
        uint256 amount,
    354
        address spoke
    355
      ) external returns (uint256) {
    356
        Asset storage asset = _assets[assetId];
    357
        SpokeData storage callerSpoke = _spokes[assetId][msg.sender];
    358
        SpokeData storage coveredSpoke = _spokes[assetId][spoke];
    359
    360
        asset.accrue();
    361
        _validateEliminateDeficit(callerSpoke, amount);
    362
    363
        uint256 deficitRay = coveredSpoke.deficitRay;
    364
        uint256 deficitAmountRay = (amount < deficitRay.fromRayUp()) ? amount.toRay() : deficitRay;
    365
    366
        uint120 shares = asset.toAddedSharesUp(deficitAmountRay.fromRayUp()).toUint120();
    367
        asset.addedShares -= shares;
    368
        callerSpoke.addedShares -= shares;
    369
        asset.deficitRay = asset.deficitRay.uncheckedSub(deficitAmountRay).toUint200();
    370
        coveredSpoke.deficitRay = deficitRay.uncheckedSub(deficitAmountRay).toUint200();
    371
    372
        asset.updateDrawnRate(assetId);
    373
    374
        emit EliminateDeficit(assetId, msg.sender, spoke, shares, deficitAmountRay);
    375
    376
        return shares;
    377
      }
    378
    379
      /// @inheritdoc IHubBase
    380
      function refreshPremium(uint256 assetId, PremiumDelta calldata premiumDelta) external {
    381
        Asset storage asset = _assets[assetId];
    382
        SpokeData storage spoke = _spokes[assetId][msg.sender];
    383
    384
        asset.accrue();
    385
        require(spoke.active, SpokeNotActive());
    386
        // no premium change allowed
    387
        require(premiumDelta.restoredPremiumRay == 0, InvalidPremiumChange());
    388
        _applyPremiumDelta(asset, spoke, premiumDelta);
    389
        asset.updateDrawnRate(assetId);
    390
    391
        emit RefreshPremium(assetId, msg.sender, premiumDelta);
    392
      }
    393
    394
      /// @inheritdoc IHubBase
    395
      function payFeeShares(uint256 assetId, uint256 shares) external {
    396
        Asset storage asset = _assets[assetId];
    397
        address feeReceiver = _assets[assetId].feeReceiver;
    398
        SpokeData storage receiver = _spokes[assetId][feeReceiver];
    399
        SpokeData storage sender = _spokes[assetId][msg.sender];
    400
    401
        asset.accrue();
    402
        _validatePayFeeShares(sender, shares);
    403
        _transferShares(sender, receiver, shares);
    404
        asset.updateDrawnRate(assetId);
    405
    406
        emit TransferShares(assetId, msg.sender, feeReceiver, shares);
    407
      }
    408
    409
      /// @inheritdoc IHub
    410
      function transferShares(uint256 assetId, uint256 shares, address toSpoke) external {
    411
        Asset storage asset = _assets[assetId];
    412
        SpokeData storage sender = _spokes[assetId][msg.sender];
    413
        SpokeData storage receiver = _spokes[assetId][toSpoke];
    414
    415
        asset.accrue();
    416
        _validateTransferShares(asset, sender, receiver, shares);
    417
        _transferShares(sender, receiver, shares);
    418
        asset.updateDrawnRate(assetId);
    419
    420
        emit TransferShares(assetId, msg.sender, toSpoke, shares);
    421
      }
    422
    423
      /// @inheritdoc IHub
    424
      function sweep(uint256 assetId, uint256 amount) external {
    425
        require(assetId < _assetCount, AssetNotListed());
    426
        Asset storage asset = _assets[assetId];
    427
    428
        asset.accrue();
    429
        _validateSweep(asset, msg.sender, amount);
    430
    431
        uint256 liquidity = asset.liquidity;
    432
        require(amount <= liquidity, InsufficientLiquidity(liquidity));
    433
    434
        asset.liquidity = liquidity.uncheckedSub(amount).toUint120();
    435
        asset.swept += amount.toUint120();
    436
        asset.updateDrawnRate(assetId);
    437
    438
        IERC20(asset.underlying).safeTransfer(msg.sender, amount);
    439
    440
        emit Sweep(assetId, msg.sender, amount);
    441
      }
    442
    443
      /// @inheritdoc IHub
    444
      function reclaim(uint256 assetId, uint256 amount) external {
    445
        require(assetId < _assetCount, AssetNotListed());
    446
        Asset storage asset = _assets[assetId];
    447
    448
        asset.accrue();
    449
        _validateReclaim(asset, msg.sender, amount);
    450
    451
        asset.liquidity += amount.toUint120();
    452
        asset.swept -= amount.toUint120();
    453
        asset.updateDrawnRate(assetId);
    454
    455
        IERC20(asset.underlying).safeTransferFrom(msg.sender, address(this), amount);
    456
    457
        emit Reclaim(assetId, msg.sender, amount);
    458
      }
    459
    460
      /// @inheritdoc IHub
    461
      function isUnderlyingListed(address underlying) external view returns (bool) {
    462
        return _underlyingAssets.contains(underlying);
    463
      }
    464
    465
      /// @inheritdoc IHub
    466
      function getAssetCount() external view returns (uint256) {
    467
        return _assetCount;
    468
      }
    469
    470
      /// @inheritdoc IHubBase
    471
      function previewAddByAssets(uint256 assetId, uint256 assets) external view returns (uint256) {
    472
        return _assets[assetId].toAddedSharesDown(assets);
    473
      }
    474
    475
      /// @inheritdoc IHubBase
    476
      function previewAddByShares(uint256 assetId, uint256 shares) external view returns (uint256) {
    477
        return _assets[assetId].toAddedAssetsUp(shares);
    478
      }
    479
    480
      /// @inheritdoc IHubBase
    481
      function previewRemoveByAssets(uint256 assetId, uint256 assets) external view returns (uint256) {
    482
        return _assets[assetId].toAddedSharesUp(assets);
    483
      }
    484
    485
      /// @inheritdoc IHubBase
    486
      function previewRemoveByShares(uint256 assetId, uint256 shares) external view returns (uint256) {
    487
        return _assets[assetId].toAddedAssetsDown(shares);
    488
      }
    489
    490
      /// @inheritdoc IHubBase
    491
      function previewDrawByAssets(uint256 assetId, uint256 assets) external view returns (uint256) {
    492
        return _assets[assetId].toDrawnSharesUp(assets);
    493
      }
    494
    495
      /// @inheritdoc IHubBase
    496
      function previewDrawByShares(uint256 assetId, uint256 shares) external view returns (uint256) {
    497
        return _assets[assetId].toDrawnAssetsDown(shares);
    498
      }
    499
    500
      /// @inheritdoc IHubBase
    501
      function previewRestoreByAssets(uint256 assetId, uint256 assets) external view returns (uint256) {
    502
        return _assets[assetId].toDrawnSharesDown(assets);
    503
      }
    504
    505
      /// @inheritdoc IHubBase
    506
      function previewRestoreByShares(uint256 assetId, uint256 shares) external view returns (uint256) {
    507
        return _assets[assetId].toDrawnAssetsUp(shares);
    508
      }
    509
    510
      /// @inheritdoc IHubBase
    511
      function getAssetUnderlyingAndDecimals(uint256 assetId) external view returns (address, uint8) {
    512
        Asset storage asset = _assets[assetId];
    513
        return (asset.underlying, asset.decimals);
    514
      }
    515
    516
      /// @inheritdoc IHubBase
    517
      function getAssetDrawnIndex(uint256 assetId) external view returns (uint256) {
    518
        return _assets[assetId].getDrawnIndex();
    519
      }
    520
    521
      /// @inheritdoc IHubBase
    522
      function getAddedAssets(uint256 assetId) external view returns (uint256) {
    523
        return _assets[assetId].totalAddedAssets();
    524
      }
    525
    526
      /// @inheritdoc IHubBase
    527
      function getAddedShares(uint256 assetId) external view returns (uint256) {
    528
        return _assets[assetId].addedShares;
    529
      }
    530
    531
      /// @inheritdoc IHubBase
    532
      function getAssetOwed(uint256 assetId) external view returns (uint256, uint256) {
    533
        Asset storage asset = _assets[assetId];
    534
        uint256 drawnIndex = asset.getDrawnIndex();
    535
        return (asset.drawn(drawnIndex), asset.premium(drawnIndex));
    536
      }
    537
    538
      /// @inheritdoc IHubBase
    539
      function getAssetTotalOwed(uint256 assetId) external view returns (uint256) {
    540
        Asset storage asset = _assets[assetId];
    541
        return asset.totalOwed(asset.getDrawnIndex());
    542
      }
    543
    544
      /// @inheritdoc IHubBase
    545
      function getAssetPremiumRay(uint256 assetId) external view returns (uint256) {
    546
        Asset storage asset = _assets[assetId];
    547
        return
    548
          Premium.calculatePremiumRay({
    549
            premiumShares: asset.premiumShares,
    550
            premiumOffsetRay: asset.premiumOffsetRay,
    551
            drawnIndex: asset.getDrawnIndex()
    552
          });
    553
      }
    554
    555
      /// @inheritdoc IHubBase
    556
      function getAssetDrawnShares(uint256 assetId) external view returns (uint256) {
    557
        return _assets[assetId].drawnShares;
    558
      }
    559
    560
      /// @inheritdoc IHubBase
    561
      function getAssetPremiumData(uint256 assetId) external view returns (uint256, int256) {
    562
        Asset storage asset = _assets[assetId];
    563
        return (asset.premiumShares, asset.premiumOffsetRay);
    564
      }
    565
    566
      /// @inheritdoc IHubBase
    567
      function getAssetLiquidity(uint256 assetId) external view returns (uint256) {
    568
        return _assets[assetId].liquidity;
    569
      }
    570
    571
      /// @inheritdoc IHubBase
    572
      function getAssetDeficitRay(uint256 assetId) external view returns (uint256) {
    573
        return _assets[assetId].deficitRay;
    574
      }
    575
    576
      /// @inheritdoc IHub
    577
      function getAsset(uint256 assetId) external view returns (Asset memory) {
    578
        return _assets[assetId];
    579
      }
    580
    581
      /// @inheritdoc IHub
    582
      function getAssetConfig(uint256 assetId) external view returns (AssetConfig memory) {
    583
        Asset storage asset = _assets[assetId];
    584
        return
    585
          AssetConfig({
    586
            feeReceiver: asset.feeReceiver,
    587
            liquidityFee: asset.liquidityFee,
    588
            irStrategy: asset.irStrategy,
    589
            reinvestmentController: asset.reinvestmentController
    590
          });
    591
      }
    592
    593
      /// @inheritdoc IHub
    594
      function getAssetAccruedFees(uint256 assetId) external view returns (uint256) {
    595
        Asset storage asset = _assets[assetId];
    596
        return asset.realizedFees + asset.getUnrealizedFees(asset.getDrawnIndex());
    597
      }
    598
    599
      /// @inheritdoc IHub
    600
      function getAssetSwept(uint256 assetId) external view returns (uint256) {
    601
        return _assets[assetId].swept;
    602
      }
    603
    604
      /// @inheritdoc IHub
    605
      function getAssetDrawnRate(uint256 assetId) external view returns (uint256) {
    606
        return _assets[assetId].drawnRate;
    607
      }
    608
    609
      /// @inheritdoc IHub
    610
      function getSpokeCount(uint256 assetId) external view returns (uint256) {
    611
        return _assetToSpokes[assetId].length();
    612
      }
    613
    614
      /// @inheritdoc IHubBase
    615
      function getSpokeAddedAssets(uint256 assetId, address spoke) external view returns (uint256) {
    616
        return _assets[assetId].toAddedAssetsDown(_spokes[assetId][spoke].addedShares);
    617
      }
    618
    619
      /// @inheritdoc IHubBase
    620
      function getSpokeAddedShares(uint256 assetId, address spoke) external view returns (uint256) {
    621
        return _spokes[assetId][spoke].addedShares;
    622
      }
    623
    624
      /// @inheritdoc IHubBase
    625
      function getSpokeOwed(uint256 assetId, address spoke) external view returns (uint256, uint256) {
    626
        Asset storage asset = _assets[assetId];
    627
        SpokeData storage spokeData = _spokes[assetId][spoke];
    628
        return (_getSpokeDrawn(asset, spokeData), _getSpokePremium(asset, spokeData));
    629
      }
    630
    631
      /// @inheritdoc IHubBase
    632
      function getSpokeTotalOwed(uint256 assetId, address spoke) external view returns (uint256) {
    633
        Asset storage asset = _assets[assetId];
    634
        SpokeData storage spokeData = _spokes[assetId][spoke];
    635
        return _getSpokeDrawn(asset, spokeData) + _getSpokePremium(asset, spokeData);
    636
      }
    637
    638
      /// @inheritdoc IHubBase
    639
      function getSpokePremiumRay(uint256 assetId, address spoke) external view returns (uint256) {
    640
        Asset storage asset = _assets[assetId];
    641
        SpokeData storage spokeData = _spokes[assetId][spoke];
    642
        return _getSpokePremiumRay(asset, spokeData);
    643
      }
    644
    645
      /// @inheritdoc IHubBase
    646
      function getSpokeDrawnShares(uint256 assetId, address spoke) external view returns (uint256) {
    647
        return _spokes[assetId][spoke].drawnShares;
    648
      }
    649
    650
      /// @inheritdoc IHubBase
    651
      function getSpokePremiumData(
    652
        uint256 assetId,
    653
        address spoke
    654
      ) external view returns (uint256, int256) {
    655
        SpokeData storage spokeData = _spokes[assetId][spoke];
    656
        return (spokeData.premiumShares, spokeData.premiumOffsetRay);
    657
      }
    658
    659
      /// @inheritdoc IHubBase
    660
      function getSpokeDeficitRay(uint256 assetId, address spoke) external view returns (uint256) {
    661
        return _spokes[assetId][spoke].deficitRay;
    662
      }
    663
    664
      /// @inheritdoc IHub
    665
      function isSpokeListed(uint256 assetId, address spoke) external view returns (bool) {
    666
        return _assetToSpokes[assetId].contains(spoke);
    667
      }
    668
    669
      /// @inheritdoc IHub
    670
      function getSpokeAddress(uint256 assetId, uint256 index) external view returns (address) {
    671
        return _assetToSpokes[assetId].at(index);
    672
      }
    673
    674
      /// @inheritdoc IHub
    675
      function getSpoke(uint256 assetId, address spoke) external view returns (SpokeData memory) {
    676
        return _spokes[assetId][spoke];
    677
      }
    678
    679
      /// @inheritdoc IHub
    680
      function getSpokeConfig(
    681
        uint256 assetId,
    682
        address spoke
    683
      ) external view returns (SpokeConfig memory) {
    684
        SpokeData storage spokeData = _spokes[assetId][spoke];
    685
        return
    686
          SpokeConfig({
    687
            addCap: spokeData.addCap,
    688
            drawCap: spokeData.drawCap,
    689
            riskPremiumThreshold: spokeData.riskPremiumThreshold,
    690
            active: spokeData.active,
    691
            paused: spokeData.paused
    692
          });
    693
      }
    694
    695
      /// @notice Adds a new spoke to an asset with default feeReceiver configuration (maximum add cap, zero draw cap).
    696
      function _addFeeReceiver(uint256 assetId, address feeReceiver) internal {
    697
        _addSpoke(assetId, feeReceiver);
    698
        _updateSpokeConfig(
    699
          assetId,
    700
          feeReceiver,
    701
          SpokeConfig({
    702
            addCap: MAX_ALLOWED_SPOKE_CAP,
    703
            drawCap: 0,
    704
            riskPremiumThreshold: 0,
    705
            active: true,
    706
            paused: false
    707
          })
    708
        );
    709
      }
    710
    711
      /// @notice Adds a spoke to an asset.
    712
      /// @dev Reverts with `SpokeAlreadyListed` if spoke is already listed for the given asset.
    713
      function _addSpoke(uint256 assetId, address spoke) internal {
    714
        require(_assetToSpokes[assetId].add(spoke), SpokeAlreadyListed());
    715
        emit AddSpoke(assetId, spoke);
    716
      }
    717
    718
      function _updateSpokeConfig(uint256 assetId, address spoke, SpokeConfig memory config) internal {
    719
        SpokeData storage spokeData = _spokes[assetId][spoke];
    720
        spokeData.addCap = config.addCap;
    721
        spokeData.drawCap = config.drawCap;
    722
        spokeData.riskPremiumThreshold = config.riskPremiumThreshold;
    723
        spokeData.active = config.active;
    724
        spokeData.paused = config.paused;
    725
        emit UpdateSpokeConfig(assetId, spoke, config);
    726
      }
    727
    728
      /// @dev Receiver `addCap` is validated in `_validateTransferShares`.
    729
      function _transferShares(
    730
        SpokeData storage sender,
    731
        SpokeData storage receiver,
    732
        uint256 shares
    733
      ) internal {
    734
        sender.addedShares -= shares.toUint120();
    735
        receiver.addedShares += shares.toUint120();
    736
      }
    737
    738
      /// @dev Applies premium deltas on asset & spoke premium owed.
    739
      /// @dev Checks premium owed decreases by exactly `restoredPremiumRay`.
    740
      /// @dev Checks updated risk premium is within allowed threshold.
    741
      /// @dev Uses last stored index; asset accrual should have already occurred.
    742
      function _applyPremiumDelta(
    743
        Asset storage asset,
    744
        SpokeData storage spoke,
    745
        PremiumDelta calldata premiumDelta
    746
      ) internal {
    747
        uint256 drawnIndex = asset.drawnIndex;
    748
    749
        // asset premium change
    750
        (asset.premiumShares, asset.premiumOffsetRay) = _validateApplyPremiumDelta(
    751
          drawnIndex,
    752
          asset.premiumShares,
    753
          asset.premiumOffsetRay,
    754
          premiumDelta
    755
        );
    756
    757
        // spoke premium change
    758
        (spoke.premiumShares, spoke.premiumOffsetRay) = _validateApplyPremiumDelta(
    759
          drawnIndex,
    760
          spoke.premiumShares,
    761
          spoke.premiumOffsetRay,
    762
          premiumDelta
    763
        );
    764
    765
        uint24 riskPremiumThreshold = spoke.riskPremiumThreshold;
    766
        require(
    767
          riskPremiumThreshold == MAX_RISK_PREMIUM_THRESHOLD ||
    768
            spoke.premiumShares <= spoke.drawnShares.percentMulUp(riskPremiumThreshold),
    769
          InvalidPremiumChange()
    770
        );
    771
      }
    772
    773
      function _mintFeeShares(Asset storage asset, uint256 assetId) internal returns (uint256) {
    774
        uint256 fees = asset.realizedFees;
    775
        uint120 shares = asset.toAddedSharesDown(fees).toUint120();
    776
        if (shares == 0) {
    777
          return 0;
    778
        }
    779
    780
        address feeReceiver = asset.feeReceiver;
    781
        SpokeData storage feeReceiverSpoke = _spokes[assetId][feeReceiver];
    782
        require(feeReceiverSpoke.active, SpokeNotActive());
    783
    784
        asset.addedShares += shares;
    785
        feeReceiverSpoke.addedShares += shares;
    786
        asset.realizedFees = 0;
    787
        emit MintFeeShares(assetId, feeReceiver, shares, fees);
    788
    789
        return shares;
    790
      }
    791
    792
      /// @dev Returns the spoke's drawn amount for a specified asset.
    793
      function _getSpokeDrawn(
    794
        Asset storage asset,
    795
        SpokeData storage spoke
    796
      ) internal view returns (uint256) {
    797
        return asset.toDrawnAssetsUp(spoke.drawnShares);
    798
      }
    799
    800
      /// @dev Returns the spoke's premium amount for a specified asset.
    801
      function _getSpokePremium(
    802
        Asset storage asset,
    803
        SpokeData storage spoke
    804
      ) internal view returns (uint256) {
    805
        return _getSpokePremiumRay(asset, spoke).fromRayUp();
    806
      }
    807
    808
      /// @dev Returns the spoke's premium amount with full precision for a specified asset.
    809
      function _getSpokePremiumRay(
    810
        Asset storage asset,
    811
        SpokeData storage spoke
    812
      ) internal view returns (uint256) {
    813
        return
    814
          Premium.calculatePremiumRay({
    815
            premiumShares: spoke.premiumShares,
    816
            premiumOffsetRay: spoke.premiumOffsetRay,
    817
            drawnIndex: asset.getDrawnIndex()
    818
          });
    819
      }
    820
    821
      /// @dev Spoke with maximum cap have unlimited add capacity.
    822
      function _validateAdd(
    823
        Asset storage asset,
    824
        SpokeData storage spoke,
    825
        uint256 amount
    826
      ) internal view {
    827
        require(amount > 0, InvalidAmount());
    828
        require(spoke.active, SpokeNotActive());
    829
        require(!spoke.paused, SpokePaused());
    830
        uint256 addCap = spoke.addCap;
    831
        require(
    832
          addCap == MAX_ALLOWED_SPOKE_CAP ||
    833
            addCap * MathUtils.uncheckedExp(10, asset.decimals) >=
    834
            asset.toAddedAssetsUp(spoke.addedShares) + amount,
    835
          AddCapExceeded(addCap)
    836
        );
    837
      }
    838
    839
      function _validateRemove(SpokeData storage spoke, uint256 amount, address to) internal view {
    840
        require(to != address(this), InvalidAddress());
    841
        require(amount > 0, InvalidAmount());
    842
        require(spoke.active, SpokeNotActive());
    843
        require(!spoke.paused, SpokePaused());
    844
      }
    845
    846
      /// @dev Spoke with maximum cap have unlimited draw capacity.
    847
      function _validateDraw(
    848
        Asset storage asset,
    849
        SpokeData storage spoke,
    850
        uint256 amount,
    851
        address to
    852
      ) internal view {
    853
        require(to != address(this), InvalidAddress());
    854
        require(amount > 0, InvalidAmount());
    855
        require(spoke.active, SpokeNotActive());
    856
        require(!spoke.paused, SpokePaused());
    857
        uint256 drawCap = spoke.drawCap;
    858
        uint256 owed = _getSpokeDrawn(asset, spoke) + _getSpokePremium(asset, spoke);
    859
        require(
    860
          drawCap == MAX_ALLOWED_SPOKE_CAP ||
    861
            drawCap * MathUtils.uncheckedExp(10, asset.decimals) >=
    862
            owed + amount + uint256(spoke.deficitRay).fromRayUp(),
    863
          DrawCapExceeded(drawCap)
    864
        );
    865
      }
    866
    867
      function _validateRestore(
    868
        Asset storage asset,
    869
        SpokeData storage spoke,
    870
        uint256 drawnAmount,
    871
        uint256 premiumAmountRay
    872
      ) internal view {
    873
        require(drawnAmount > 0 || premiumAmountRay > 0, InvalidAmount());
    874
        require(spoke.active, SpokeNotActive());
    875
        require(!spoke.paused, SpokePaused());
    876
        uint256 drawn = _getSpokeDrawn(asset, spoke);
    877
        uint256 premiumRay = _getSpokePremiumRay(asset, spoke);
    878
        require(drawnAmount <= drawn, SurplusDrawnRestored(drawn));
    879
        require(premiumAmountRay <= premiumRay, SurplusPremiumRayRestored(premiumRay));
    880
      }
    881
    882
      function _validateReportDeficit(
    883
        Asset storage asset,
    884
        SpokeData storage spoke,
    885
        uint256 drawnAmount,
    886
        uint256 premiumAmountRay
    887
      ) internal view {
    888
        require(spoke.active, SpokeNotActive());
    889
        require(!spoke.paused, SpokePaused());
    890
        require(drawnAmount > 0 || premiumAmountRay > 0, InvalidAmount());
    891
        uint256 drawn = _getSpokeDrawn(asset, spoke);
    892
        uint256 premiumRay = _getSpokePremiumRay(asset, spoke);
    893
        require(drawnAmount <= drawn, SurplusDrawnDeficitReported(drawn));
    894
        require(premiumAmountRay <= premiumRay, SurplusPremiumRayDeficitReported(premiumRay));
    895
      }
    896
    897
      function _validateEliminateDeficit(SpokeData storage spoke, uint256 amount) internal view {
    898
        require(spoke.active, SpokeNotActive());
    899
        require(amount > 0, InvalidAmount());
    900
      }
    901
    902
      function _validatePayFeeShares(SpokeData storage senderSpoke, uint256 feeShares) internal view {
    903
        require(senderSpoke.active, SpokeNotActive());
    904
        require(!senderSpoke.paused, SpokePaused());
    905
        require(feeShares > 0, InvalidShares());
    906
      }
    907
    908
      function _validateTransferShares(
    909
        Asset storage asset,
    910
        SpokeData storage sender,
    911
        SpokeData storage receiver,
    912
        uint256 shares
    913
      ) internal view {
    914
        require(sender.active && receiver.active, SpokeNotActive());
    915
        require(!sender.paused && !receiver.paused, SpokePaused());
    916
        require(shares > 0, InvalidShares());
    917
        uint256 addCap = receiver.addCap;
    918
        require(
    919
          addCap == MAX_ALLOWED_SPOKE_CAP ||
    920
            addCap * MathUtils.uncheckedExp(10, asset.decimals) >=
    921
            asset.toAddedAssetsUp(receiver.addedShares + shares),
    922
          AddCapExceeded(addCap)
    923
        );
    924
      }
    925
    926
      function _validateSweep(Asset storage asset, address caller, uint256 amount) internal view {
    927
        // sufficient check to disallow when controller unset
    928
        require(caller == asset.reinvestmentController, OnlyReinvestmentController());
    929
        require(amount > 0, InvalidAmount());
    930
      }
    931
    932
      function _validateReclaim(Asset storage asset, address caller, uint256 amount) internal view {
    933
        // sufficient check to disallow when controller unset
    934
        require(caller == asset.reinvestmentController, OnlyReinvestmentController());
    935
        require(amount > 0, InvalidAmount());
    936
      }
    937
    938
      /// @dev Validates applied premium delta for given premium data and returns updated premium data.
    939
      function _validateApplyPremiumDelta(
    940
        uint256 drawnIndex,
    941
        uint256 premiumShares,
    942
        int256 premiumOffsetRay,
    943
        PremiumDelta calldata premiumDelta
    944
      ) internal pure returns (uint120, int200) {
    945
        uint256 premiumRayBefore = Premium.calculatePremiumRay({
    946
          premiumShares: premiumShares,
    947
          premiumOffsetRay: premiumOffsetRay,
    948
          drawnIndex: drawnIndex
    949
        });
    950
    951
        uint256 newPremiumShares = premiumShares.add(premiumDelta.sharesDelta);
    952
        int256 newPremiumOffsetRay = premiumOffsetRay + premiumDelta.offsetRayDelta;
    953
    954
        uint256 premiumRayAfter = Premium.calculatePremiumRay({
    955
          premiumShares: newPremiumShares,
    956
          premiumOffsetRay: newPremiumOffsetRay,
    957
          drawnIndex: drawnIndex
    958
        });
    959
    960
        require(
    961
          premiumRayAfter + premiumDelta.restoredPremiumRay == premiumRayBefore,
    962
          InvalidPremiumChange()
    963
        );
    964
        return (newPremiumShares.toUint120(), newPremiumOffsetRay.toInt200());
    965
      }
    966
    }
    967
    0.0% src/hub/HubConfigurator.sol
    Lines covered: 0 / 140 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity 0.8.28;
    4
    5
    import {IERC20Metadata} from 'src/dependencies/openzeppelin/IERC20Metadata.sol';
    6
    import {Ownable2Step, Ownable} from 'src/dependencies/openzeppelin/Ownable2Step.sol';
    7
    import {SafeCast} from 'src/dependencies/openzeppelin/SafeCast.sol';
    8
    import {IHub} from 'src/hub/interfaces/IHub.sol';
    9
    import {IHubConfigurator} from 'src/hub/interfaces/IHubConfigurator.sol';
    10
    11
    /// @title HubConfigurator
    12
    /// @author Aave Labs
    13
    /// @notice Handles administrative functions on the Hub.
    14
    /// @dev Must be granted permission by the Hub.
    15
    contract HubConfigurator is Ownable2Step, IHubConfigurator {
    16
      using SafeCast for uint256;
    17
    18
      /// @dev Constructor.
    19
      /// @param owner_ The address of the owner.
    20
      constructor(address owner_) Ownable(owner_) {}
    21
    22
      /// @inheritdoc IHubConfigurator
    23
      function addAsset(
    24
        address hub,
    25
        address underlying,
    26
        address feeReceiver,
    27
        uint256 liquidityFee,
    28
        address irStrategy,
    29
        bytes calldata irData
    30
      ) external onlyOwner returns (uint256) {
    31
        IHub targetHub = IHub(hub);
    32
        uint256 assetId = targetHub.addAsset(
    33
          underlying,
    34
          IERC20Metadata(underlying).decimals(),
    35
          feeReceiver,
    36
          irStrategy,
    37
          irData
    38
        );
    39
        _updateLiquidityFee(targetHub, assetId, liquidityFee);
    40
        return assetId;
    41
      }
    42
    43
      /// @inheritdoc IHubConfigurator
    44
      function addAsset(
    45
        address hub,
    46
        address underlying,
    47
        uint8 decimals,
    48
        address feeReceiver,
    49
        uint256 liquidityFee,
    50
        address irStrategy,
    51
        bytes calldata irData
    52
      ) external onlyOwner returns (uint256) {
    53
        IHub targetHub = IHub(hub);
    54
        uint256 assetId = targetHub.addAsset(underlying, decimals, feeReceiver, irStrategy, irData);
    55
        _updateLiquidityFee(targetHub, assetId, liquidityFee);
    56
        return assetId;
    57
      }
    58
    59
      /// @inheritdoc IHubConfigurator
    60
      function updateLiquidityFee(
    61
        address hub,
    62
        uint256 assetId,
    63
        uint256 liquidityFee
    64
      ) external onlyOwner {
    65
        _updateLiquidityFee(IHub(hub), assetId, liquidityFee);
    66
      }
    67
    68
      /// @inheritdoc IHubConfigurator
    69
      function updateFeeReceiver(address hub, uint256 assetId, address feeReceiver) external onlyOwner {
    70
        IHub targetHub = IHub(hub);
    71
        IHub.AssetConfig memory config = targetHub.getAssetConfig(assetId);
    72
        config.feeReceiver = feeReceiver;
    73
        targetHub.updateAssetConfig(assetId, config, new bytes(0));
    74
      }
    75
    76
      /// @inheritdoc IHubConfigurator
    77
      function updateFeeConfig(
    78
        address hub,
    79
        uint256 assetId,
    80
        uint256 liquidityFee,
    81
        address feeReceiver
    82
      ) external onlyOwner {
    83
        IHub targetHub = IHub(hub);
    84
        IHub.AssetConfig memory config = targetHub.getAssetConfig(assetId);
    85
        config.liquidityFee = liquidityFee.toUint16();
    86
        config.feeReceiver = feeReceiver;
    87
        targetHub.updateAssetConfig(assetId, config, new bytes(0));
    88
      }
    89
    90
      /// @inheritdoc IHubConfigurator
    91
      function updateInterestRateStrategy(
    92
        address hub,
    93
        uint256 assetId,
    94
        address irStrategy,
    95
        bytes calldata irData
    96
      ) external onlyOwner {
    97
        IHub targetHub = IHub(hub);
    98
        IHub.AssetConfig memory config = targetHub.getAssetConfig(assetId);
    99
        config.irStrategy = irStrategy;
    100
        targetHub.updateAssetConfig(assetId, config, irData);
    101
      }
    102
    103
      /// @inheritdoc IHubConfigurator
    104
      function updateReinvestmentController(
    105
        address hub,
    106
        uint256 assetId,
    107
        address reinvestmentController
    108
      ) external onlyOwner {
    109
        IHub targetHub = IHub(hub);
    110
        IHub.AssetConfig memory config = targetHub.getAssetConfig(assetId);
    111
        config.reinvestmentController = reinvestmentController;
    112
        targetHub.updateAssetConfig(assetId, config, new bytes(0));
    113
      }
    114
    115
      /// @inheritdoc IHubConfigurator
    116
      function freezeAsset(address hub, uint256 assetId) external onlyOwner {
    117
        IHub targetHub = IHub(hub);
    118
        uint256 spokesCount = targetHub.getSpokeCount(assetId);
    119
    120
        for (uint256 i = 0; i < spokesCount; ++i) {
    121
          address spoke = targetHub.getSpokeAddress(assetId, i);
    122
          IHub.SpokeConfig memory config = targetHub.getSpokeConfig(assetId, spoke);
    123
          config.addCap = 0;
    124
          config.drawCap = 0;
    125
          targetHub.updateSpokeConfig(assetId, spoke, config);
    126
        }
    127
      }
    128
    129
      /// @inheritdoc IHubConfigurator
    130
      function deactivateAsset(address hub, uint256 assetId) external onlyOwner {
    131
        IHub targetHub = IHub(hub);
    132
        uint256 spokesCount = targetHub.getSpokeCount(assetId);
    133
        for (uint256 i = 0; i < spokesCount; ++i) {
    134
          address spoke = targetHub.getSpokeAddress(assetId, i);
    135
          IHub.SpokeConfig memory config = targetHub.getSpokeConfig(assetId, spoke);
    136
          config.active = false;
    137
          targetHub.updateSpokeConfig(assetId, spoke, config);
    138
        }
    139
      }
    140
    141
      /// @inheritdoc IHubConfigurator
    142
      function pauseAsset(address hub, uint256 assetId) external onlyOwner {
    143
        IHub targetHub = IHub(hub);
    144
        uint256 spokesCount = targetHub.getSpokeCount(assetId);
    145
        for (uint256 i = 0; i < spokesCount; ++i) {
    146
          address spoke = targetHub.getSpokeAddress(assetId, i);
    147
          IHub.SpokeConfig memory config = targetHub.getSpokeConfig(assetId, spoke);
    148
          config.paused = true;
    149
          targetHub.updateSpokeConfig(assetId, spoke, config);
    150
        }
    151
      }
    152
    153
      /// @inheritdoc IHubConfigurator
    154
      function addSpoke(
    155
        address hub,
    156
        address spoke,
    157
        uint256 assetId,
    158
        IHub.SpokeConfig calldata config
    159
      ) external onlyOwner {
    160
        IHub(hub).addSpoke(assetId, spoke, config);
    161
      }
    162
    163
      /// @inheritdoc IHubConfigurator
    164
      function addSpokeToAssets(
    165
        address hub,
    166
        address spoke,
    167
        uint256[] calldata assetIds,
    168
        IHub.SpokeConfig[] calldata configs
    169
      ) external onlyOwner {
    170
        uint256 assetCount = assetIds.length;
    171
        require(assetCount == configs.length, MismatchedConfigs());
    172
        for (uint256 i = 0; i < assetCount; ++i) {
    173
          IHub(hub).addSpoke(assetIds[i], spoke, configs[i]);
    174
        }
    175
      }
    176
    177
      /// @inheritdoc IHubConfigurator
    178
      function updateSpokeActive(
    179
        address hub,
    180
        uint256 assetId,
    181
        address spoke,
    182
        bool active
    183
      ) external onlyOwner {
    184
        IHub targetHub = IHub(hub);
    185
        IHub.SpokeConfig memory config = targetHub.getSpokeConfig(assetId, spoke);
    186
        config.active = active;
    187
        targetHub.updateSpokeConfig(assetId, spoke, config);
    188
      }
    189
    190
      /// @inheritdoc IHubConfigurator
    191
      function updateSpokePaused(
    192
        address hub,
    193
        uint256 assetId,
    194
        address spoke,
    195
        bool paused
    196
      ) external onlyOwner {
    197
        IHub targetHub = IHub(hub);
    198
        IHub.SpokeConfig memory config = targetHub.getSpokeConfig(assetId, spoke);
    199
        config.paused = paused;
    200
        targetHub.updateSpokeConfig(assetId, spoke, config);
    201
      }
    202
    203
      /// @inheritdoc IHubConfigurator
    204
      function updateSpokeSupplyCap(
    205
        address hub,
    206
        uint256 assetId,
    207
        address spoke,
    208
        uint256 addCap
    209
      ) external onlyOwner {
    210
        IHub targetHub = IHub(hub);
    211
        IHub.SpokeConfig memory config = targetHub.getSpokeConfig(assetId, spoke);
    212
        config.addCap = addCap.toUint40();
    213
        targetHub.updateSpokeConfig(assetId, spoke, config);
    214
      }
    215
    216
      /// @inheritdoc IHubConfigurator
    217
      function updateSpokeDrawCap(
    218
        address hub,
    219
        uint256 assetId,
    220
        address spoke,
    221
        uint256 drawCap
    222
      ) external onlyOwner {
    223
        IHub targetHub = IHub(hub);
    224
        IHub.SpokeConfig memory config = targetHub.getSpokeConfig(assetId, spoke);
    225
        config.drawCap = drawCap.toUint40();
    226
        targetHub.updateSpokeConfig(assetId, spoke, config);
    227
      }
    228
    229
      /// @inheritdoc IHubConfigurator
    230
      function updateSpokeRiskPremiumThreshold(
    231
        address hub,
    232
        uint256 assetId,
    233
        address spoke,
    234
        uint256 riskPremiumThreshold
    235
      ) external onlyOwner {
    236
        IHub targetHub = IHub(hub);
    237
        IHub.SpokeConfig memory config = targetHub.getSpokeConfig(assetId, spoke);
    238
        config.riskPremiumThreshold = riskPremiumThreshold.toUint24();
    239
        targetHub.updateSpokeConfig(assetId, spoke, config);
    240
      }
    241
    242
      /// @inheritdoc IHubConfigurator
    243
      function updateSpokeCaps(
    244
        address hub,
    245
        uint256 assetId,
    246
        address spoke,
    247
        uint256 addCap,
    248
        uint256 drawCap
    249
      ) external onlyOwner {
    250
        _updateSpokeCaps(IHub(hub), assetId, spoke, addCap, drawCap);
    251
      }
    252
    253
      /// @inheritdoc IHubConfigurator
    254
      function deactivateSpoke(address hub, address spoke) external onlyOwner {
    255
        IHub targetHub = IHub(hub);
    256
        uint256 assetCount = targetHub.getAssetCount();
    257
        for (uint256 assetId = 0; assetId < assetCount; ++assetId) {
    258
          if (targetHub.isSpokeListed(assetId, spoke)) {
    259
            IHub.SpokeConfig memory config = targetHub.getSpokeConfig(assetId, spoke);
    260
            config.active = false;
    261
            targetHub.updateSpokeConfig(assetId, spoke, config);
    262
          }
    263
        }
    264
      }
    265
    266
      /// @inheritdoc IHubConfigurator
    267
      function pauseSpoke(address hub, address spoke) external onlyOwner {
    268
        IHub targetHub = IHub(hub);
    269
        uint256 assetCount = targetHub.getAssetCount();
    270
        for (uint256 assetId = 0; assetId < assetCount; ++assetId) {
    271
          if (targetHub.isSpokeListed(assetId, spoke)) {
    272
            IHub.SpokeConfig memory config = targetHub.getSpokeConfig(assetId, spoke);
    273
            config.paused = true;
    274
            targetHub.updateSpokeConfig(assetId, spoke, config);
    275
          }
    276
        }
    277
      }
    278
    279
      /// @inheritdoc IHubConfigurator
    280
      function freezeSpoke(address hub, address spoke) external onlyOwner {
    281
        IHub targetHub = IHub(hub);
    282
        uint256 assetCount = targetHub.getAssetCount();
    283
        for (uint256 assetId = 0; assetId < assetCount; ++assetId) {
    284
          if (targetHub.isSpokeListed(assetId, spoke)) {
    285
            IHub.SpokeConfig memory config = targetHub.getSpokeConfig(assetId, spoke);
    286
            config.addCap = 0;
    287
            config.drawCap = 0;
    288
            targetHub.updateSpokeConfig(assetId, spoke, config);
    289
          }
    290
        }
    291
      }
    292
    293
      /// @inheritdoc IHubConfigurator
    294
      function updateInterestRateData(
    295
        address hub,
    296
        uint256 assetId,
    297
        bytes calldata irData
    298
      ) external onlyOwner {
    299
        IHub(hub).setInterestRateData(assetId, irData);
    300
      }
    301
    302
      /// @dev Updates spoke caps without changing the active flag.
    303
      function _updateSpokeCaps(
    304
        IHub hub,
    305
        uint256 assetId,
    306
        address spoke,
    307
        uint256 addCap,
    308
        uint256 drawCap
    309
      ) internal {
    310
        IHub.SpokeConfig memory config = hub.getSpokeConfig(assetId, spoke);
    311
        config.addCap = addCap.toUint40();
    312
        config.drawCap = drawCap.toUint40();
    313
        hub.updateSpokeConfig(assetId, spoke, config);
    314
      }
    315
    316
      function _updateLiquidityFee(IHub hub, uint256 assetId, uint256 liquidityFee) internal {
    317
        IHub.AssetConfig memory config = hub.getAssetConfig(assetId);
    318
        config.liquidityFee = liquidityFee.toUint16();
    319
        hub.updateAssetConfig(assetId, config, new bytes(0));
    320
      }
    321
    }
    322
    0.0% src/hub/interfaces/IAssetInterestRateStrategy.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    import {IBasicInterestRateStrategy} from 'src/hub/interfaces/IBasicInterestRateStrategy.sol';
    6
    7
    /// @title IAssetInterestRateStrategy
    8
    /// @author Aave Labs
    9
    /// @notice Interface of the kink-based asset interest rate strategy.
    10
    interface IAssetInterestRateStrategy is IBasicInterestRateStrategy {
    11
      /// @notice Holds the interest rate data for a given asset.
    12
      /// @dev optimalUsageRatio The optimal usage ratio, in BPS. Maximum and minimum values are defined by `MAX_OPTIMAL_RATIO` and `MIN_OPTIMAL_RATIO`.
    13
      /// @dev baseVariableBorrowRate The base variable borrow rate, in BPS.
    14
      /// @dev variableRateSlope1 The slope of the variable interest curve, before hitting the optimal usage ratio, in BPS.
    15
      /// @dev variableRateSlope2 The slope of the variable interest curve, after hitting the optimal usage ratio, in BPS.
    16
      struct InterestRateData {
    17
        uint16 optimalUsageRatio;
    18
        uint32 baseVariableBorrowRate;
    19
        uint32 variableRateSlope1;
    20
        uint32 variableRateSlope2;
    21
      }
    22
    23
      /// @notice Emitted when new interest rate data is set for an asset.
    24
      /// @param hub The address of the associated Hub.
    25
      /// @param assetId Identifier of the asset that has new interest rate data set.
    26
      /// @param optimalUsageRatio The optimal usage ratio, in BPS.
    27
      /// @param baseVariableBorrowRate The base variable borrow rate, in BPS.
    28
      /// @param variableRateSlope1 The slope of the variable interest curve, before hitting the optimal usage ratio, in BPS.
    29
      /// @param variableRateSlope2 The slope of the variable interest curve, after hitting the optimal usage ratio, in BPS.
    30
      event UpdateRateData(
    31
        address indexed hub,
    32
        uint256 indexed assetId,
    33
        uint256 optimalUsageRatio,
    34
        uint256 baseVariableBorrowRate,
    35
        uint256 variableRateSlope1,
    36
        uint256 variableRateSlope2
    37
      );
    38
    39
      /// @notice Thrown when the given address is invalid.
    40
      error InvalidAddress();
    41
    42
      /// @notice Thrown when the caller is not the Hub.
    43
      error OnlyHub();
    44
    45
      /// @notice Thrown when the max possible rate is greater than `MAX_BORROW_RATE`.
    46
      error InvalidMaxRate();
    47
    48
      /// @notice Thrown when slope 2 (after kink point) is less than slope 1 (before kink point).
    49
      error Slope2MustBeGteSlope1();
    50
    51
      /// @notice Thrown when the optimal usage ratio is less than `MIN_OPTIMAL_POINT` or greater than `MAX_OPTIMAL_POINT`.
    52
      error InvalidOptimalUsageRatio();
    53
    54
      /// @notice Returns the full InterestRateData struct for the given asset.
    55
      /// @param assetId The identifier of the asset to get the data for.
    56
      /// @return The InterestRateData struct for the given asset, all in BPS.
    57
      function getInterestRateData(uint256 assetId) external view returns (InterestRateData memory);
    58
    59
      /// @notice Returns the optimal usage rate for the given asset.
    60
      /// @param assetId The identifier of the asset to get the optimal usage ratio for.
    61
      /// @return The optimal usage ratio, in BPS.
    62
      function getOptimalUsageRatio(uint256 assetId) external view returns (uint256);
    63
    64
      /// @notice Returns the base variable borrow rate.
    65
      /// @param assetId The identifier of the asset to get the base variable borrow rate for.
    66
      /// @return The base variable borrow rate, in BPS.
    67
      function getBaseVariableBorrowRate(uint256 assetId) external view returns (uint256);
    68
    69
      /// @notice Returns the variable rate slope below optimal usage ratio.
    70
      /// @dev Applicable when usage ratio > 0 and <= OPTIMAL_USAGE_RATIO.
    71
      /// @param assetId The identifier of the asset to get the variable rate slope 1 for.
    72
      /// @return The variable rate slope, in BPS.
    73
      function getVariableRateSlope1(uint256 assetId) external view returns (uint256);
    74
    75
      /// @notice Returns the variable rate slope above optimal usage ratio.
    76
      /// @dev Applicable when usage ratio > OPTIMAL_USAGE_RATIO.
    77
      /// @param assetId The identifier of the asset to get the variable rate slope 2 for.
    78
      /// @return The variable rate slope, in BPS.
    79
      function getVariableRateSlope2(uint256 assetId) external view returns (uint256);
    80
    81
      /// @notice Returns the maximum variable borrow rate.
    82
      /// @param assetId The identifier of the asset to get the maximum variable borrow rate for.
    83
      /// @return The maximum variable borrow rate, in BPS.
    84
      function getMaxVariableBorrowRate(uint256 assetId) external view returns (uint256);
    85
    86
      /// @notice Returns the maximum value achievable for the borrow rate.
    87
      /// @return The maximum rate, in BPS.
    88
      function MAX_BORROW_RATE() external view returns (uint256);
    89
    90
      /// @notice Returns the minimum optimal usage ratio.
    91
      /// @return The minimum optimal usage ratio, in BPS.
    92
      function MIN_OPTIMAL_RATIO() external view returns (uint256);
    93
    94
      /// @notice Returns the maximum optimal usage ratio.
    95
      /// @return The maximum optimal usage ratio, in BPS.
    96
      function MAX_OPTIMAL_RATIO() external view returns (uint256);
    97
    98
      /// @notice Returns the associated address of the Hub.
    99
      /// @return The address of the Hub.
    100
      function HUB() external view returns (address);
    101
    }
    102
    0.0% src/hub/interfaces/IBasicInterestRateStrategy.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    /// @title IBasicInterestRateStrategy
    6
    /// @author Aave Labs
    7
    /// @notice Basic interface for any rate strategy.
    8
    interface IBasicInterestRateStrategy {
    9
      /// @notice Thrown when the interest rate data is not set for the asset.
    10
      /// @param assetId The identifier of the asset with no interest rate data set.
    11
      error InterestRateDataNotSet(uint256 assetId);
    12
    13
      /// @notice Sets the interest rate parameters for a specified asset.
    14
      /// @param assetId The identifier of the asset.
    15
      /// @param data The encoded parameters used to configure the interest rate of the asset.
    16
      function setInterestRateData(uint256 assetId, bytes calldata data) external;
    17
    18
      /// @notice Calculates the interest rate depending on the asset's state and configurations.
    19
      /// @param assetId The identifier of the asset.
    20
      /// @param liquidity The current available liquidity of the asset.
    21
      /// @param drawn The current drawn amount of the asset.
    22
      /// @param deficit The current deficit of the asset.
    23
      /// @param swept The current swept (reinvested) amount of the asset.
    24
      /// @return The interest rate expressed in RAY.
    25
      function calculateInterestRate(
    26
        uint256 assetId,
    27
        uint256 liquidity,
    28
        uint256 drawn,
    29
        uint256 deficit,
    30
        uint256 swept
    31
      ) external view returns (uint256);
    32
    }
    33
    0.0% src/hub/interfaces/IHub.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    import {IAccessManaged} from 'src/dependencies/openzeppelin/IAccessManaged.sol';
    6
    import {IHubBase} from 'src/hub/interfaces/IHubBase.sol';
    7
    8
    /// @title IHub
    9
    /// @author Aave Labs
    10
    /// @notice Full interface for the Hub.
    11
    interface IHub is IHubBase, IAccessManaged {
    12
      /// @notice Asset position and configuration data.
    13
      /// @dev liquidity The liquidity available to be accessed, expressed in asset units.
    14
      /// @dev realizedFees The amount of fees realized but not yet minted, expressed in asset units.
    15
      /// @dev decimals The number of decimals of the underlying asset.
    16
      /// @dev addedShares The total shares added across all spokes.
    17
      /// @dev swept The outstanding liquidity which has been invested by the reinvestment controller, expressed in asset units.
    18
      /// @dev premiumOffsetRay The total premium offset across all spokes, used to calculate the premium, expressed in asset units and scaled by RAY.
    19
      /// @dev drawnShares The total drawn shares across all spokes.
    20
      /// @dev premiumShares The total premium shares across all spokes.
    21
      /// @dev liquidityFee The protocol fee charged on drawn and premium liquidity growth, expressed in BPS.
    22
      /// @dev drawnIndex The drawn index which monotonically increases according to the drawn rate, expressed in RAY.
    23
      /// @dev drawnRate The rate at which drawn assets grows, expressed in RAY.
    24
      /// @dev lastUpdateTimestamp The timestamp of the last accrual.
    25
      /// @dev underlying The address of the underlying asset.
    26
      /// @dev irStrategy The address of the interest rate strategy.
    27
      /// @dev reinvestmentController The address of the reinvestment controller.
    28
      /// @dev feeReceiver The address of the fee receiver spoke.
    29
      /// @dev deficitRay The amount of outstanding bad debt across all spokes, expressed in asset units and scaled by RAY.
    30
      struct Asset {
    31
        uint120 liquidity;
    32
        uint120 realizedFees;
    33
        uint8 decimals;
    34
        //
    35
        uint120 addedShares;
    36
        uint120 swept;
    37
        //
    38
        int200 premiumOffsetRay;
    39
        //
    40
        uint120 drawnShares;
    41
        uint120 premiumShares;
    42
        uint16 liquidityFee;
    43
        //
    44
        uint120 drawnIndex;
    45
        uint96 drawnRate;
    46
        uint40 lastUpdateTimestamp;
    47
        //
    48
        address underlying;
    49
        //
    50
        address irStrategy;
    51
        //
    52
        address reinvestmentController;
    53
        //
    54
        address feeReceiver;
    55
        //
    56
        uint200 deficitRay;
    57
      }
    58
    59
      /// @notice Asset configuration. Subset of the `Asset` struct.
    60
      struct AssetConfig {
    61
        address feeReceiver;
    62
        uint16 liquidityFee;
    63
        address irStrategy;
    64
        address reinvestmentController;
    65
      }
    66
    67
      /// @notice Spoke position and configuration data.
    68
      /// @dev drawnShares The drawn shares of a spoke for a given asset.
    69
      /// @dev premiumShares The premium shares of a spoke for a given asset.
    70
      /// @dev premiumOffsetRay The premium offset of a spoke for a given asset, used to calculate the premium, expressed in asset units and scaled by RAY.
    71
      /// @dev addedShares The added shares of a spoke for a given asset.
    72
      /// @dev addCap The maximum amount that can be added by a spoke, expressed in whole assets (not scaled by decimals). A value of `MAX_ALLOWED_SPOKE_CAP` indicates no cap.
    73
      /// @dev drawCap The maximum amount that can be drawn by a spoke, expressed in whole assets (not scaled by decimals). A value of `MAX_ALLOWED_SPOKE_CAP` indicates no cap.
    74
      /// @dev riskPremiumThreshold The maximum ratio of premium to drawn shares a spoke can have, expressed in BPS. A value of `MAX_RISK_PREMIUM_THRESHOLD` indicates no threshold.
    75
      /// @dev active True if the spoke is prevented from performing any actions.
    76
      /// @dev paused True if the spoke is prevented from performing actions that instantly update the liquidity.
    77
      /// @dev deficitRay The deficit reported by a spoke for a given asset, expressed in asset units and scaled by RAY.
    78
      struct SpokeData {
    79
        uint120 drawnShares;
    80
        uint120 premiumShares;
    81
        //
    82
        int200 premiumOffsetRay;
    83
        //
    84
        uint120 addedShares;
    85
        uint40 addCap;
    86
        uint40 drawCap;
    87
        uint24 riskPremiumThreshold;
    88
        bool active;
    89
        bool paused;
    90
        //
    91
        uint200 deficitRay;
    92
      }
    93
    94
      /// @notice Spoke configuration data. Subset of the `SpokeData` struct.
    95
      struct SpokeConfig {
    96
        uint40 addCap;
    97
        uint40 drawCap;
    98
        uint24 riskPremiumThreshold;
    99
        bool active;
    100
        bool paused;
    101
      }
    102
    103
      /// @notice Emitted when an asset is added.
    104
      /// @param assetId The identifier of the asset.
    105
      /// @param underlying The address of the underlying asset.
    106
      /// @param decimals The number of decimals of the asset.
    107
      event AddAsset(uint256 indexed assetId, address indexed underlying, uint8 decimals);
    108
    109
      /// @notice Emitted when an asset is updated.
    110
      /// @param assetId The identifier of the asset.
    111
      /// @param drawnIndex The new drawn index of the asset.
    112
      /// @param drawnRate The new drawn rate of the asset.
    113
      /// @param accruedFees The accrued fees of the asset since the last mint.
    114
      event UpdateAsset(
    115
        uint256 indexed assetId,
    116
        uint256 drawnIndex,
    117
        uint256 drawnRate,
    118
        uint256 accruedFees
    119
      );
    120
    121
      /// @notice Emitted when an asset configuration is updated.
    122
      /// @param assetId The identifier of the asset.
    123
      /// @param config The new asset configuration struct.
    124
      event UpdateAssetConfig(uint256 indexed assetId, AssetConfig config);
    125
    126
      /// @notice Emitted when a spoke is added.
    127
      /// @param assetId The identifier of the asset.
    128
      /// @param spoke The address of the spoke.
    129
      event AddSpoke(uint256 indexed assetId, address indexed spoke);
    130
    131
      /// @notice Emitted when a spoke configuration is updated.
    132
      /// @param assetId The identifier of the asset.
    133
      /// @param spoke The address of the spoke.
    134
      /// @param config The new spoke configuration struct.
    135
      event UpdateSpokeConfig(uint256 indexed assetId, address indexed spoke, SpokeConfig config);
    136
    137
      /// @notice Emitted when fees are minted to the fee receiver spoke.
    138
      /// @param assetId The identifier of the asset.
    139
      /// @param feeReceiver The address of the current fee receiver spoke.
    140
      /// @param shares The amount of shares minted.
    141
      /// @param assets The amount of assets used to mint the shares.
    142
      event MintFeeShares(
    143
        uint256 indexed assetId,
    144
        address indexed feeReceiver,
    145
        uint256 shares,
    146
        uint256 assets
    147
      );
    148
    149
      /// @notice Emitted when an amount of liquidity is invested by the reinvestment controller.
    150
      /// @param assetId The identifier of the asset.
    151
      /// @param reinvestmentController The active asset controller.
    152
      /// @param amount The amount invested.
    153
      event Sweep(uint256 indexed assetId, address indexed reinvestmentController, uint256 amount);
    154
    155
      /// @notice Emitted when an amount of liquidity is reclaimed (from swept liquidity) by the reinvestment controller.
    156
      /// @param assetId The identifier of the asset.
    157
      /// @param reinvestmentController The active asset controller.
    158
      /// @param amount The amount reclaimed.
    159
      event Reclaim(uint256 indexed assetId, address indexed reinvestmentController, uint256 amount);
    160
    161
      /// @notice Emitted when deficit is eliminated.
    162
      /// @param assetId The identifier of the asset.
    163
      /// @param callerSpoke The spoke that eliminated the deficit using its supplied shares.
    164
      /// @param coveredSpoke The spoke for which the deficit was eliminated.
    165
      /// @param shares The amount of shares removed.
    166
      /// @param deficitAmountRay The amount of deficit eliminated, expressed in asset units and scaled by RAY.
    167
      event EliminateDeficit(
    168
        uint256 indexed assetId,
    169
        address indexed callerSpoke,
    170
        address indexed coveredSpoke,
    171
        uint256 shares,
    172
        uint256 deficitAmountRay
    173
      );
    174
    175
      /// @notice Thrown when an underlying asset is already listed.
    176
      error UnderlyingAlreadyListed();
    177
    178
      /// @notice Thrown when an asset is not listed.
    179
      error AssetNotListed();
    180
    181
      /// @notice Thrown when the add cap is exceeded.
    182
      /// @param addCap The current `addCap` of the asset, expressed in whole assets (not scaled by decimals).
    183
      error AddCapExceeded(uint256 addCap);
    184
    185
      /// @notice Thrown when the available liquidity is insufficient.
    186
      /// @param liquidity The current available liquidity.
    187
      error InsufficientLiquidity(uint256 liquidity);
    188
    189
      /// @notice Thrown when the transferred liquidity is insufficient.
    190
      /// @param liquidityNeeded The amount of additional liquidity needed.
    191
      error InsufficientTransferred(uint256 liquidityNeeded);
    192
    193
      /// @notice Thrown when the draw cap is exceeded.
    194
      /// @param drawCap The current `drawCap` of the asset, expressed in whole assets (not scaled by decimals).
    195
      error DrawCapExceeded(uint256 drawCap);
    196
    197
      /// @notice Thrown when a surplus amount of drawn is restored.
    198
      /// @param maxAllowedRestore The maximum allowed drawn amount to restore.
    199
      error SurplusDrawnRestored(uint256 maxAllowedRestore);
    200
    201
      /// @notice Thrown when a surplus amount of premium is restored.
    202
      /// @param maxAllowedRestoreRay The maximum allowed premium amount to restore, expressed in asset units and scaled by RAY.
    203
      error SurplusPremiumRayRestored(uint256 maxAllowedRestoreRay);
    204
    205
      /// @notice Thrown when the premium change is invalid.
    206
      error InvalidPremiumChange();
    207
    208
      /// @notice Thrown when a surplus amount of drawn is reported as deficit.
    209
      /// @param maxAllowedDeficit The maximum allowed drawn to report as deficit.
    210
      error SurplusDrawnDeficitReported(uint256 maxAllowedDeficit);
    211
    212
      /// @notice Thrown when a surplus amount of premium is reported as deficit.
    213
      /// @param maxAllowedDeficitRay The maximum allowed premium to report as deficit, expressed in asset units and scaled by RAY.
    214
      error SurplusPremiumRayDeficitReported(uint256 maxAllowedDeficitRay);
    215
    216
      /// @notice Thrown when a spoke is not active.
    217
      error SpokeNotActive();
    218
    219
      /// @notice Thrown when a spoke is paused.
    220
      error SpokePaused();
    221
    222
      /// @notice Thrown when a new reinvestment controller is the zero address and the asset has existing swept liquidity.
    223
      error InvalidReinvestmentController();
    224
    225
      /// @notice Thrown when an invalid reinvestment controller attempts to perform a `sweep` action.
    226
      error OnlyReinvestmentController();
    227
    228
      /// @notice Thrown when a spoke being added is already listed.
    229
      error SpokeAlreadyListed();
    230
    231
      /// @notice Thrown when a spoke being updated is not listed.
    232
      error SpokeNotListed();
    233
    234
      /// @notice Thrown when the amount is invalid.
    235
      error InvalidAmount();
    236
    237
      /// @notice Thrown when the shares amount is invalid.
    238
      error InvalidShares();
    239
    240
      /// @notice Thrown when an input address is invalid.
    241
      error InvalidAddress();
    242
    243
      /// @notice Thrown if the liquidity fee is invalid when updating an asset configuration.
    244
      error InvalidLiquidityFee();
    245
    246
      /// @notice Thrown when the asset decimals exceed the maximum allowed decimals.
    247
      error InvalidAssetDecimals();
    248
    249
      /// @notice Thrown if the interest rate strategy or data are invalid when updating an asset configuration.
    250
      /// @dev The `irData` must be empty if the interest rate strategy is not updated.
    251
      error InvalidInterestRateStrategy();
    252
    253
      /// @notice Adds a new asset to the Hub.
    254
      /// @dev The same underlying asset address cannot be added as an asset multiple times.
    255
      /// @dev The fee receiver is added as a new spoke with maximum add cap and zero draw cap.
    256
      /// @param underlying The address of the underlying asset.
    257
      /// @param decimals The number of decimals of `underlying`.
    258
      /// @param feeReceiver The address of the fee receiver spoke.
    259
      /// @param irStrategy The address of the interest rate strategy contract.
    260
      /// @param irData The interest rate data to apply to the given asset encoded in bytes.
    261
      /// @return The unique identifier of the added asset.
    262
      function addAsset(
    263
        address underlying,
    264
        uint8 decimals,
    265
        address feeReceiver,
    266
        address irStrategy,
    267
        bytes calldata irData
    268
      ) external returns (uint256);
    269
    270
      /// @notice Updates the configuration of an asset.
    271
      /// @dev If the fee receiver is updated, adds it as a new spoke with maximum add cap and zero draw cap, and sets old fee receiver caps to zero.
    272
      /// @dev If the fee receiver is updated, accrued fees are minted as shares before the update if their value exceeds one share.
    273
      /// @dev If the interest rate strategy is updated, it is configured with `irData`. Otherwise, `irData` must be empty.
    274
      /// @param assetId The identifier of the asset.
    275
      /// @param config The new configuration for the asset.
    276
      /// @param irData The interest rate data to apply to the given asset, encoded in bytes.
    277
      function updateAssetConfig(
    278
        uint256 assetId,
    279
        AssetConfig calldata config,
    280
        bytes calldata irData
    281
      ) external;
    282
    283
      /// @notice Registers a new spoke for a specific asset in the Hub.
    284
      /// @dev Reverts with `SpokeAlreadyListed` if spoke is already listed.
    285
      /// @param assetId The identifier of the asset.
    286
      /// @param spoke The address of the spoke to add.
    287
      /// @param params The configuration parameters for the spoke.
    288
      function addSpoke(uint256 assetId, address spoke, SpokeConfig calldata params) external;
    289
    290
      /// @notice Updates the configuration of a spoke for a specific asset.
    291
      /// @param assetId The identifier of the asset.
    292
      /// @param spoke The address of the spoke to update.
    293
      /// @param config The new configuration for the spoke.
    294
      function updateSpokeConfig(uint256 assetId, address spoke, SpokeConfig calldata config) external;
    295
    296
      /// @notice Updates the interest rate strategy for a specified asset.
    297
      /// @param assetId The identifier of the asset.
    298
      /// @param irData The interest rate data to apply to the given asset, encoded in bytes.
    299
      function setInterestRateData(uint256 assetId, bytes calldata irData) external;
    300
    301
      /// @notice Mints shares to the fee receiver from accrued fees.
    302
      /// @dev No op when fees are worth less than one share.
    303
      /// @param assetId The identifier of the asset.
    304
      /// @return The amount of shares minted.
    305
      function mintFeeShares(uint256 assetId) external returns (uint256);
    306
    307
      /// @notice Eliminates deficit by removing supplied shares of caller spoke.
    308
      /// @dev Only callable by active spokes.
    309
      /// @param assetId The identifier of the asset.
    310
      /// @param amount The amount of deficit to eliminate.
    311
      /// @param spoke The spoke for which the deficit is eliminated.
    312
      /// @return The amount of shares removed.
    313
      function eliminateDeficit(
    314
        uint256 assetId,
    315
        uint256 amount,
    316
        address spoke
    317
      ) external returns (uint256);
    318
    319
      /// @notice Allows a spoke to transfer its supplied shares of an asset to another spoke.
    320
      /// @dev Only callable by spokes.
    321
      /// @param assetId The identifier of the asset.
    322
      /// @param shares The amount of shares to move.
    323
      /// @param toSpoke The address of the recipient spoke.
    324
      function transferShares(uint256 assetId, uint256 shares, address toSpoke) external;
    325
    326
      /// @notice Sweeps an amount of liquidity of the corresponding asset and sends it to the configured reinvestment controller.
    327
      /// @dev The controller handles the actual reinvestment of funds, redistribution of interest, and investment caps.
    328
      /// @param assetId The identifier of the asset.
    329
      /// @param amount The amount to sweep.
    330
      function sweep(uint256 assetId, uint256 amount) external;
    331
    332
      /// @notice Reclaims an amount of liquidity of the corresponding asset from the configured reinvestment controller.
    333
      /// @dev The controller can only reclaim up to swept amount. All accrued interest is distributed offchain.
    334
      /// @param assetId The identifier of the asset.
    335
      /// @param amount The amount to reclaim.
    336
      function reclaim(uint256 assetId, uint256 amount) external;
    337
    338
      /// @notice Returns whether the underlying is listed as an asset.
    339
      /// @param underlying The address of the underlying asset.
    340
      /// @return True if the underlying asset is listed.
    341
      function isUnderlyingListed(address underlying) external view returns (bool);
    342
    343
      /// @notice Returns the number of listed assets.
    344
      /// @return The number of listed assets.
    345
      function getAssetCount() external view returns (uint256);
    346
    347
      /// @notice Returns information regarding the specified asset.
    348
      /// @dev `drawnIndex`, `drawnRate` and `lastUpdateTimestamp` can be outdated due to passage of time.
    349
      /// @param assetId The identifier of the asset.
    350
      /// @return The asset struct.
    351
      function getAsset(uint256 assetId) external view returns (Asset memory);
    352
    353
      /// @notice Returns the asset configuration for the specified asset.
    354
      /// @param assetId The identifier of the asset.
    355
      /// @return The asset configuration struct.
    356
      function getAssetConfig(uint256 assetId) external view returns (AssetConfig memory);
    357
    358
      /// @notice Returns the accrued fees for the asset, expressed in asset units.
    359
      /// @dev Accrued fees are excluded from total added assets.
    360
      /// @param assetId The identifier of the asset.
    361
      /// @return The amount of accrued fees.
    362
      function getAssetAccruedFees(uint256 assetId) external view returns (uint256);
    363
    364
      /// @notice Returns the amount of liquidity swept by the reinvestment controller for the specified asset.
    365
      /// @param assetId The identifier of the asset.
    366
      /// @return The amount of liquidity swept.
    367
      function getAssetSwept(uint256 assetId) external view returns (uint256);
    368
    369
      /// @notice Returns the current drawn rate for the specified asset.
    370
      /// @param assetId The identifier of the asset.
    371
      /// @return The current drawn rate of the asset.
    372
      function getAssetDrawnRate(uint256 assetId) external view returns (uint256);
    373
    374
      /// @notice Returns the number of spokes listed for the specified asset.
    375
      /// @param assetId The identifier of the asset.
    376
      /// @return The number of spokes.
    377
      function getSpokeCount(uint256 assetId) external view returns (uint256);
    378
    379
      /// @notice Returns whether the spoke is listed for the specified asset.
    380
      /// @param assetId The identifier of the asset.
    381
      /// @param spoke The address of the spoke.
    382
      /// @return True if the spoke is listed.
    383
      function isSpokeListed(uint256 assetId, address spoke) external view returns (bool);
    384
    385
      /// @notice Returns the address of the spoke for an asset at the given index.
    386
      /// @param assetId The identifier of the asset.
    387
      /// @param index The index of the spoke.
    388
      /// @return The address of the spoke.
    389
      function getSpokeAddress(uint256 assetId, uint256 index) external view returns (address);
    390
    391
      /// @notice Returns the spoke data struct.
    392
      /// @param assetId The identifier of the asset.
    393
      /// @param spoke The address of the spoke.
    394
      /// @return The spoke data struct.
    395
      function getSpoke(uint256 assetId, address spoke) external view returns (SpokeData memory);
    396
    397
      /// @notice Returns the spoke configuration struct.
    398
      /// @param assetId The identifier of the asset.
    399
      /// @param spoke The address of the spoke.
    400
      /// @return The spoke configuration struct.
    401
      function getSpokeConfig(
    402
        uint256 assetId,
    403
        address spoke
    404
      ) external view returns (SpokeConfig memory);
    405
    406
      /// @notice Returns the maximum allowed number of decimals for the underlying asset.
    407
      /// @return The maximum number of decimals (inclusive).
    408
      function MAX_ALLOWED_UNDERLYING_DECIMALS() external view returns (uint8);
    409
    410
      /// @notice Returns the minimum allowed number of decimals for the underlying asset.
    411
      /// @return The minimum number of decimals (inclusive).
    412
      function MIN_ALLOWED_UNDERLYING_DECIMALS() external view returns (uint8);
    413
    414
      /// @notice Returns the maximum value for any spoke cap (add or draw).
    415
      /// @dev The value is not inclusive; using the maximum value indicates no cap.
    416
      /// @return The maximum cap value, expressed in asset units.
    417
      function MAX_ALLOWED_SPOKE_CAP() external view returns (uint40);
    418
    419
      /// @notice Returns the maximum value for any spoke risk premium threshold.
    420
      /// @dev The value is not inclusive; using the maximum value indicates no threshold.
    421
      /// @return The maximum risk premium threshold, expressed in BPS.
    422
      function MAX_RISK_PREMIUM_THRESHOLD() external view returns (uint24);
    423
    }
    424
    0.0% src/hub/interfaces/IHubBase.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    /// @title IHubBase
    6
    /// @author Aave Labs
    7
    /// @notice Minimal interface for Hub.
    8
    interface IHubBase {
    9
      /// @notice Changes to premium owed accounting.
    10
      /// @dev sharesDelta The change in premium shares.
    11
      /// @dev offsetRayDelta The change in premium offset, expressed in asset units and scaled by RAY.
    12
      /// @dev restoredPremiumRay The restored premium, expressed in asset units and scaled by RAY.
    13
      struct PremiumDelta {
    14
        int256 sharesDelta;
    15
        int256 offsetRayDelta;
    16
        uint256 restoredPremiumRay;
    17
      }
    18
    19
      /// @notice Emitted on the `add` action.
    20
      /// @param assetId The identifier of the asset.
    21
      /// @param spoke The address of the spoke.
    22
      /// @param shares The amount of shares added.
    23
      /// @param amount The amount of assets added.
    24
      event Add(uint256 indexed assetId, address indexed spoke, uint256 shares, uint256 amount);
    25
    26
      /// @notice Emitted on the `remove` action.
    27
      /// @param assetId The identifier of the asset.
    28
      /// @param spoke The address of the spoke.
    29
      /// @param shares The amount of shares removed.
    30
      /// @param amount The amount of assets removed.
    31
      event Remove(uint256 indexed assetId, address indexed spoke, uint256 shares, uint256 amount);
    32
    33
      /// @notice Emitted on the `draw` action.
    34
      /// @param assetId The identifier of the asset.
    35
      /// @param spoke The address of the spoke.
    36
      /// @param drawnShares The amount of drawn shares.
    37
      /// @param drawnAmount The amount of drawn assets.
    38
      event Draw(
    39
        uint256 indexed assetId,
    40
        address indexed spoke,
    41
        uint256 drawnShares,
    42
        uint256 drawnAmount
    43
      );
    44
    45
      /// @notice Emitted on the `restore` action.
    46
      /// @param assetId The identifier of the asset.
    47
      /// @param spoke The address of the spoke.
    48
      /// @param drawnShares The amount of drawn shares.
    49
      /// @param premiumDelta The premium delta data struct.
    50
      /// @param drawnAmount The amount of drawn assets restored.
    51
      /// @param premiumAmount The amount of premium assets restored.
    52
      event Restore(
    53
        uint256 indexed assetId,
    54
        address indexed spoke,
    55
        uint256 drawnShares,
    56
        PremiumDelta premiumDelta,
    57
        uint256 drawnAmount,
    58
        uint256 premiumAmount
    59
      );
    60
    61
      /// @notice Emitted on the `refreshPremium` action.
    62
      /// @param assetId The identifier of the asset.
    63
      /// @param spoke The address of the spoke.
    64
      /// @param premiumDelta The premium delta data struct.
    65
      event RefreshPremium(uint256 indexed assetId, address indexed spoke, PremiumDelta premiumDelta);
    66
    67
      /// @notice Emitted on the `reportDeficit` action.
    68
      /// @param assetId The identifier of the asset.
    69
      /// @param spoke The address of the spoke.
    70
      /// @param drawnShares The amount of drawn shares reported as deficit.
    71
      /// @param premiumDelta The premium delta data struct.
    72
      /// @param deficitAmountRay The amount of deficit reported, expressed in asset units and scaled by RAY.
    73
      event ReportDeficit(
    74
        uint256 indexed assetId,
    75
        address indexed spoke,
    76
        uint256 drawnShares,
    77
        PremiumDelta premiumDelta,
    78
        uint256 deficitAmountRay
    79
      );
    80
    81
      /// @notice Emitted on the `transferShares` action.
    82
      /// @param assetId The identifier of the asset.
    83
      /// @param sender The address of the sender.
    84
      /// @param receiver The address of the receiver.
    85
      /// @param shares The amount of shares transferred.
    86
      event TransferShares(
    87
        uint256 indexed assetId,
    88
        address indexed sender,
    89
        address indexed receiver,
    90
        uint256 shares
    91
      );
    92
    93
      /// @notice Add asset on behalf of user.
    94
      /// @dev Only callable by active spokes.
    95
      /// @dev Underlying assets must be transferred to the Hub before invocation.
    96
      /// @dev Extra underlying liquidity retained in the Hub can be skimmed by any Spoke through this action.
    97
      /// @param assetId The identifier of the asset.
    98
      /// @param amount The amount of asset liquidity to add.
    99
      /// @return The amount of shares added.
    100
      function add(uint256 assetId, uint256 amount) external returns (uint256);
    101
    102
      /// @notice Remove added asset on behalf of user.
    103
      /// @dev Only callable by active spokes.
    104
      /// @param assetId The identifier of the asset.
    105
      /// @param amount The amount of asset liquidity to remove.
    106
      /// @param to The address to transfer the assets to.
    107
      /// @return The amount of shares removed.
    108
      function remove(uint256 assetId, uint256 amount, address to) external returns (uint256);
    109
    110
      /// @notice Draw assets on behalf of user.
    111
      /// @dev Only callable by active spokes.
    112
      /// @param assetId The identifier of the asset.
    113
      /// @param amount The amount of assets to draw.
    114
      /// @param to The address to transfer the underlying assets to.
    115
      /// @return The amount of drawn shares.
    116
      function draw(uint256 assetId, uint256 amount, address to) external returns (uint256);
    117
    118
      /// @notice Restore assets on behalf of user.
    119
      /// @dev Only callable by active spokes.
    120
      /// @dev Interest is always paid off first from premium, then from drawn.
    121
      /// @dev Underlying assets must be transferred to the Hub before invocation.
    122
      /// @dev Extra underlying liquidity retained in the Hub can be skimmed by any Spoke through this action.
    123
      /// @param assetId The identifier of the asset.
    124
      /// @param drawnAmount The drawn amount to restore.
    125
      /// @param premiumDelta The premium delta to apply which signal premium repayment.
    126
      /// @return The amount of drawn shares restored.
    127
      function restore(
    128
        uint256 assetId,
    129
        uint256 drawnAmount,
    130
        PremiumDelta calldata premiumDelta
    131
      ) external returns (uint256);
    132
    133
      /// @notice Reports deficit.
    134
      /// @dev Only callable by active spokes.
    135
      /// @param assetId The identifier of the asset.
    136
      /// @param drawnAmount The drawn amount to report as deficit.
    137
      /// @param premiumDelta The premium delta to apply which signal premium deficit.
    138
      /// @return The amount of drawn shares reported as deficit.
    139
      function reportDeficit(
    140
        uint256 assetId,
    141
        uint256 drawnAmount,
    142
        PremiumDelta calldata premiumDelta
    143
      ) external returns (uint256);
    144
    145
      /// @notice Refreshes premium accounting.
    146
      /// @dev Only callable by active spokes.
    147
      /// @dev Asset and spoke premium should not decrease.
    148
      /// @param assetId The identifier of the asset.
    149
      /// @param premiumDelta The change in premium.
    150
      function refreshPremium(uint256 assetId, PremiumDelta calldata premiumDelta) external;
    151
    152
      /// @notice Transfers `shares` amount of existing `addedShares` of caller spoke to `feeReceiver`.
    153
      /// @dev Only callable by active spokes. Utilized to pay liquidation fee.
    154
      /// @param assetId The identifier of the asset.
    155
      /// @param shares The amount of shares to pay to feeReceiver.
    156
      function payFeeShares(uint256 assetId, uint256 shares) external;
    157
    158
      /// @notice Converts the specified amount of assets to shares upon an `add` action.
    159
      /// @dev Rounds down to the nearest shares amount.
    160
      /// @param assetId The identifier of the asset.
    161
      /// @param assets The amount of assets to convert to shares amount.
    162
      /// @return The amount of shares converted from assets amount.
    163
      function previewAddByAssets(uint256 assetId, uint256 assets) external view returns (uint256);
    164
    165
      /// @notice Converts the specified shares amount to assets amount added upon an `add` action.
    166
      /// @dev Rounds up to the nearest assets amount.
    167
      /// @param assetId The identifier of the asset.
    168
      /// @param shares The amount of shares to convert to assets amount.
    169
      /// @return The amount of assets converted from shares amount.
    170
      function previewAddByShares(uint256 assetId, uint256 shares) external view returns (uint256);
    171
    172
      /// @notice Converts the specified amount of assets to shares amount removed upon a `remove` action.
    173
      /// @dev Rounds up to the nearest shares amount.
    174
      /// @param assetId The identifier of the asset.
    175
      /// @param assets The amount of assets to convert to shares amount.
    176
      /// @return The amount of shares converted from assets amount.
    177
      function previewRemoveByAssets(uint256 assetId, uint256 assets) external view returns (uint256);
    178
    179
      /// @notice Converts the specified amount of shares to assets amount removed upon a `remove` action.
    180
      /// @dev Rounds down to the nearest assets amount.
    181
      /// @param assetId The identifier of the asset.
    182
      /// @param shares The amount of shares to convert to assets amount.
    183
      /// @return The amount of assets converted from shares amount.
    184
      function previewRemoveByShares(uint256 assetId, uint256 shares) external view returns (uint256);
    185
    186
      /// @notice Converts the specified amount of assets to shares amount drawn upon a `draw` action.
    187
      /// @dev Rounds up to the nearest shares amount.
    188
      /// @param assetId The identifier of the asset.
    189
      /// @param assets The amount of assets to convert to shares amount.
    190
      /// @return The amount of shares converted from assets amount.
    191
      function previewDrawByAssets(uint256 assetId, uint256 assets) external view returns (uint256);
    192
    193
      /// @notice Converts the specified amount of shares to assets amount drawn upon a `draw` action.
    194
      /// @dev Rounds down to the nearest assets amount.
    195
      /// @param assetId The identifier of the asset.
    196
      /// @param shares The amount of shares to convert to assets amount.
    197
      /// @return The amount of assets converted from shares amount.
    198
      function previewDrawByShares(uint256 assetId, uint256 shares) external view returns (uint256);
    199
    200
      /// @notice Converts the specified amount of assets to shares amount restored upon a `restore` action.
    201
      /// @dev Rounds down to the nearest shares amount.
    202
      /// @param assetId The identifier of the asset.
    203
      /// @param assets The amount of assets to convert to shares amount.
    204
      /// @return The amount of shares converted from assets amount.
    205
      function previewRestoreByAssets(uint256 assetId, uint256 assets) external view returns (uint256);
    206
    207
      /// @notice Converts the specified amount of shares to assets amount restored upon a `restore` action.
    208
      /// @dev Rounds up to the nearest assets amount.
    209
      /// @param assetId The identifier of the asset.
    210
      /// @param shares The amount of drawn shares to convert to assets amount.
    211
      /// @return The amount of assets converted from shares amount.
    212
      function previewRestoreByShares(uint256 assetId, uint256 shares) external view returns (uint256);
    213
    214
      /// @notice Returns the underlying address and decimals of the specified asset.
    215
      /// @param assetId The identifier of the asset.
    216
      /// @return The underlying address of the asset.
    217
      /// @return The decimals of the asset.
    218
      function getAssetUnderlyingAndDecimals(uint256 assetId) external view returns (address, uint8);
    219
    220
      /// @notice Calculates the current drawn index for the specified asset.
    221
      /// @param assetId The identifier of the asset.
    222
      /// @return The current drawn index of the asset.
    223
      function getAssetDrawnIndex(uint256 assetId) external view returns (uint256);
    224
    225
      /// @notice Returns the total amount of the specified asset added to the Hub.
    226
      /// @param assetId The identifier of the asset.
    227
      /// @return The amount of the asset added.
    228
      function getAddedAssets(uint256 assetId) external view returns (uint256);
    229
    230
      /// @notice Returns the total amount of shares of the specified asset added to the Hub.
    231
      /// @param assetId The identifier of the asset.
    232
      /// @return The amount of shares of the asset added.
    233
      function getAddedShares(uint256 assetId) external view returns (uint256);
    234
    235
      /// @notice Returns the amount of owed drawn and premium assets for the specified asset.
    236
      /// @param assetId The identifier of the asset.
    237
      /// @return The amount of owed drawn assets.
    238
      /// @return The amount of owed premium assets.
    239
      function getAssetOwed(uint256 assetId) external view returns (uint256, uint256);
    240
    241
      /// @notice Returns the total amount of assets owed to the Hub.
    242
      /// @param assetId The identifier of the asset.
    243
      /// @return The total amount of the assets owed.
    244
      function getAssetTotalOwed(uint256 assetId) external view returns (uint256);
    245
    246
      /// @notice Returns the amount of owed premium with full precision for specified asset.
    247
      /// @param assetId The identifier of the asset.
    248
      /// @return The amount of premium owed, expressed in asset units and scaled by RAY.
    249
      function getAssetPremiumRay(uint256 assetId) external view returns (uint256);
    250
    251
      /// @notice Returns the amount of drawn shares of the specified asset.
    252
      /// @param assetId The identifier of the asset.
    253
      /// @return The amount of drawn shares.
    254
      function getAssetDrawnShares(uint256 assetId) external view returns (uint256);
    255
    256
      /// @notice Returns the information regarding premium shares of the specified asset.
    257
      /// @param assetId The identifier of the asset.
    258
      /// @return The amount of premium shares owed to the asset.
    259
      /// @return The premium offset of the asset, expressed in asset units and scaled by RAY.
    260
      function getAssetPremiumData(uint256 assetId) external view returns (uint256, int256);
    261
    262
      /// @notice Returns the amount of available liquidity for the specified asset.
    263
      /// @param assetId The identifier of the asset.
    264
      /// @return The amount of available liquidity.
    265
      function getAssetLiquidity(uint256 assetId) external view returns (uint256);
    266
    267
      /// @notice Returns the amount of deficit with full precision of the specified asset.
    268
      /// @param assetId The identifier of the asset.
    269
      /// @return The amount of deficit, expressed in asset units and scaled by RAY.
    270
      function getAssetDeficitRay(uint256 assetId) external view returns (uint256);
    271
    272
      /// @notice Returns the total amount of the specified assets added to the Hub by the specified spoke.
    273
      /// @dev If spoke is `asset.feeReceiver`, includes converted `unrealizedFeeShares` in return value.
    274
      /// @param assetId The identifier of the asset.
    275
      /// @param spoke The address of the spoke.
    276
      /// @return The amount of added assets.
    277
      function getSpokeAddedAssets(uint256 assetId, address spoke) external view returns (uint256);
    278
    279
      /// @notice Returns the total amount of shares of the specified asset added to the Hub by the specified spoke.
    280
      /// @dev If spoke is `asset.feeReceiver`, includes `unrealizedFeeShares` in return value.
    281
      /// @param assetId The identifier of the asset.
    282
      /// @param spoke The address of the spoke.
    283
      /// @return The amount of added shares.
    284
      function getSpokeAddedShares(uint256 assetId, address spoke) external view returns (uint256);
    285
    286
      /// @notice Returns the amount of the specified assets owed to the Hub by the specified spoke.
    287
      /// @param assetId The identifier of the asset.
    288
      /// @param spoke The address of the spoke.
    289
      /// @return The amount of owed drawn assets.
    290
      /// @return The amount of owed premium assets.
    291
      function getSpokeOwed(uint256 assetId, address spoke) external view returns (uint256, uint256);
    292
    293
      /// @notice Returns the total amount of the specified asset owed to the Hub by the specified spoke.
    294
      /// @param assetId The identifier of the asset.
    295
      /// @param spoke The address of the spoke.
    296
      /// @return The total amount of the asset owed.
    297
      function getSpokeTotalOwed(uint256 assetId, address spoke) external view returns (uint256);
    298
    299
      /// @notice Returns the amount of owed premium with full precision for specified asset and spoke.
    300
      /// @param assetId The identifier of the asset.
    301
      /// @param spoke The address of the spoke.
    302
      /// @return The amount of owed premium assets, expressed in asset units and scaled by RAY.
    303
      function getSpokePremiumRay(uint256 assetId, address spoke) external view returns (uint256);
    304
    305
      /// @notice Returns the amount of drawn shares of the specified asset by the specified spoke.
    306
      /// @param assetId The identifier of the asset.
    307
      /// @param spoke The address of the spoke.
    308
      /// @return The amount of drawn shares.
    309
      function getSpokeDrawnShares(uint256 assetId, address spoke) external view returns (uint256);
    310
    311
      /// @notice Returns the information regarding premium shares of the specified asset for the specified spoke.
    312
      /// @param assetId The identifier of the asset.
    313
      /// @param spoke The address of the spoke.
    314
      /// @return The amount of premium shares.
    315
      /// @return The premium offset, expressed in asset units and scaled by RAY.
    316
      function getSpokePremiumData(
    317
        uint256 assetId,
    318
        address spoke
    319
      ) external view returns (uint256, int256);
    320
    321
      /// @notice Returns the amount of a given spoke's deficit with full precision for the specified asset.
    322
      /// @param assetId The identifier of the asset.
    323
      /// @param spoke The address of the spoke.
    324
      /// @return The amount of deficit, expressed in asset units and scaled by RAY.
    325
      function getSpokeDeficitRay(uint256 assetId, address spoke) external view returns (uint256);
    326
    }
    327
    0.0% src/hub/interfaces/IHubConfigurator.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    import {IHub} from 'src/hub/interfaces/IHub.sol';
    6
    7
    /// @title IHubConfigurator
    8
    /// @author Aave Labs
    9
    /// @notice Interface for HubConfigurator.
    10
    interface IHubConfigurator {
    11
      /// @notice Thrown when the list of assets and spoke configs are not the same length in `addSpokeToAssets`.
    12
      error MismatchedConfigs();
    13
    14
      /// @notice Adds a new asset to the Hub.
    15
      /// @dev Retrieves the decimals of the underlying asset from its ERC20 contract.
    16
      /// @dev The fee receiver is automatically added as a spoke with maximum caps.
    17
      /// @param hub The address of the Hub contract.
    18
      /// @param underlying The address of the underlying asset.
    19
      /// @param feeReceiver The address of the fee receiver spoke.
    20
      /// @param liquidityFee The liquidity fee of the asset, in BPS.
    21
      /// @param irStrategy The address of the interest rate strategy contract.
    22
      /// @param irData The interest rate data to apply to the given asset, encoded in bytes.
    23
      /// @return The unique identifier of the added asset.
    24
      function addAsset(
    25
        address hub,
    26
        address underlying,
    27
        address feeReceiver,
    28
        uint256 liquidityFee,
    29
        address irStrategy,
    30
        bytes calldata irData
    31
      ) external returns (uint256);
    32
    33
      /// @notice Adds a new asset to the Hub.
    34
      /// @dev Retrieves the decimals of the underlying asset from its ERC20 contract.
    35
      /// @dev The fee receiver is automatically added as a spoke with maximum caps.
    36
      /// @param hub The address of the Hub contract.
    37
      /// @param underlying The address of the underlying asset.
    38
      /// @param decimals The number of decimals of the asset.
    39
      /// @param feeReceiver The address of the fee receiver spoke.
    40
      /// @param liquidityFee The liquidity fee of the asset, in BPS.
    41
      /// @param irStrategy The address of the interest rate strategy contract.
    42
      /// @param irData The interest rate data to apply to the given asset, encoded in bytes.
    43
      /// @return The unique identifier of the added asset.
    44
      function addAsset(
    45
        address hub,
    46
        address underlying,
    47
        uint8 decimals,
    48
        address feeReceiver,
    49
        uint256 liquidityFee,
    50
        address irStrategy,
    51
        bytes calldata irData
    52
      ) external returns (uint256);
    53
    54
      /// @notice Updates the liquidity fee of an asset.
    55
      /// @param hub The address of the Hub contract.
    56
      /// @param assetId The identifier of the asset.
    57
      /// @param liquidityFee The new liquidity fee.
    58
      function updateLiquidityFee(address hub, uint256 assetId, uint256 liquidityFee) external;
    59
    60
      /// @notice Updates the fee receiver of an asset.
    61
      /// @dev The fee receiver cannot be zero.
    62
      /// @param hub The address of the Hub contract.
    63
      /// @param assetId The identifier of the asset.
    64
      /// @param feeReceiver The new fee receiver.
    65
      function updateFeeReceiver(address hub, uint256 assetId, address feeReceiver) external;
    66
    67
      /// @notice Updates the liquidity fee and fee receiver of an asset.
    68
      /// @dev The fee receiver cannot be zero.
    69
      /// @param hub The address of the Hub contract.
    70
      /// @param assetId The identifier of the asset.
    71
      /// @param liquidityFee The new liquidity fee.
    72
      /// @param feeReceiver The new fee receiver.
    73
      function updateFeeConfig(
    74
        address hub,
    75
        uint256 assetId,
    76
        uint256 liquidityFee,
    77
        address feeReceiver
    78
      ) external;
    79
    80
      /// @notice Updates the interest rate strategy of an asset.
    81
      /// @param hub The address of the Hub contract.
    82
      /// @param assetId The identifier of the asset.
    83
      /// @param irStrategy The new interest rate strategy.
    84
      /// @param irData The interest rate data to apply to the given asset, encoded in bytes.
    85
      function updateInterestRateStrategy(
    86
        address hub,
    87
        uint256 assetId,
    88
        address irStrategy,
    89
        bytes calldata irData
    90
      ) external;
    91
    92
      /// @notice Updates the reinvestment controller of an asset.
    93
      /// @param hub The address of the Hub contract.
    94
      /// @param assetId The identifier of the asset.
    95
      /// @param reinvestmentController The new reinvestment controller.
    96
      function updateReinvestmentController(
    97
        address hub,
    98
        uint256 assetId,
    99
        address reinvestmentController
    100
      ) external;
    101
    102
      /// @notice Freezes an asset.
    103
      /// @param hub The address of the Hub contract.
    104
      /// @param assetId The identifier of the asset.
    105
      function freezeAsset(address hub, uint256 assetId) external;
    106
    107
      /// @notice Deactivates an asset.
    108
      /// @param hub The address of the Hub contract.
    109
      /// @param assetId The identifier of the asset.
    110
      function deactivateAsset(address hub, uint256 assetId) external;
    111
    112
      /// @notice Pauses an asset.
    113
      /// @param hub The address of the Hub contract.
    114
      /// @param assetId The identifier of the asset.
    115
      function pauseAsset(address hub, uint256 assetId) external;
    116
    117
      /// @notice Register the spoke for the specified asset in the Hub.
    118
      /// @param hub The address of the Hub contract.
    119
      /// @param assetId The identifier of the asset to register the spoke for.
    120
      /// @param spoke The address of the Spoke contract.
    121
      /// @param config The Spoke configuration to register.
    122
      function addSpoke(
    123
        address hub,
    124
        address spoke,
    125
        uint256 assetId,
    126
        IHub.SpokeConfig calldata config
    127
      ) external;
    128
    129
      /// @notice Registers the same spoke for multiple assets with the Hub, each with their own configuration.
    130
      /// @dev The i-th asset identifier in `assetIds` corresponds to the i-th configuration in `configs`.
    131
      /// @param hub The address of the Hub contract.
    132
      /// @param spoke The address of the Spoke contract.
    133
      /// @param assetIds The list of asset identifiers to register the spoke for.
    134
      /// @param configs The list of Spoke configurations to register.
    135
      function addSpokeToAssets(
    136
        address hub,
    137
        address spoke,
    138
        uint256[] calldata assetIds,
    139
        IHub.SpokeConfig[] calldata configs
    140
      ) external;
    141
    142
      /// @notice Updates the active flag of an asset's spoke.
    143
      /// @param hub The address of the Hub contract.
    144
      /// @param assetId The identifier of the asset.
    145
      /// @param spoke The address of the spoke.
    146
      /// @param active The new active flag.
    147
      function updateSpokeActive(address hub, uint256 assetId, address spoke, bool active) external;
    148
    149
      /// @notice Updates the paused flag of an asset's spoke.
    150
      /// @param hub The address of the Hub contract.
    151
      /// @param assetId The identifier of the asset.
    152
      /// @param spoke The address of the spoke.
    153
      /// @param paused The new paused flag.
    154
      function updateSpokePaused(address hub, uint256 assetId, address spoke, bool paused) external;
    155
    156
      /// @notice Updates the supply cap of an asset's spoke.
    157
      /// @param hub The address of the Hub contract.
    158
      /// @param assetId The identifier of the asset.
    159
      /// @param spoke The address of the spoke.
    160
      /// @param addCap The new supply cap.
    161
      function updateSpokeSupplyCap(
    162
        address hub,
    163
        uint256 assetId,
    164
        address spoke,
    165
        uint256 addCap
    166
      ) external;
    167
    168
      /// @notice Updates the draw cap of an asset's spoke.
    169
      /// @param hub The address of the Hub contract.
    170
      /// @param assetId The identifier of the asset.
    171
      /// @param spoke The address of the spoke.
    172
      /// @param drawCap The new draw cap.
    173
      function updateSpokeDrawCap(
    174
        address hub,
    175
        uint256 assetId,
    176
        address spoke,
    177
        uint256 drawCap
    178
      ) external;
    179
    180
      /// @notice Updates the risk premium threshold of an asset's spoke.
    181
      /// @param hub The address of the Hub contract.
    182
      /// @param assetId The identifier of the asset.
    183
      /// @param spoke The address of the spoke.
    184
      /// @param riskPremiumThreshold The new risk premium threshold.
    185
      function updateSpokeRiskPremiumThreshold(
    186
        address hub,
    187
        uint256 assetId,
    188
        address spoke,
    189
        uint256 riskPremiumThreshold
    190
      ) external;
    191
    192
      /// @notice Updates the caps of an asset's spoke.
    193
      /// @param hub The address of the Hub contract.
    194
      /// @param assetId The identifier of the asset.
    195
      /// @param spoke The address of the spoke.
    196
      /// @param addCap The new supply cap.
    197
      /// @param drawCap The new draw cap.
    198
      function updateSpokeCaps(
    199
        address hub,
    200
        uint256 assetId,
    201
        address spoke,
    202
        uint256 addCap,
    203
        uint256 drawCap
    204
      ) external;
    205
    206
      /// @notice Deactivates all assets of a spoke on a specified hub by setting the active flag to false.
    207
      /// @param hub The address of the Hub contract.
    208
      /// @param spoke The address of the spoke.
    209
      function deactivateSpoke(address hub, address spoke) external;
    210
    211
      /// @notice Pauses all assets of a spoke on a specified hub by setting the paused flag to true.
    212
      /// @param hub The address of the Hub contract.
    213
      /// @param spoke The address of the spoke.
    214
      function pauseSpoke(address hub, address spoke) external;
    215
    216
      /// @notice Freezes all assets of a spoke on a specified hub by setting the add and draw caps to zero.
    217
      /// @param hub The address of the Hub contract.
    218
      /// @param spoke The address of the spoke.
    219
      function freezeSpoke(address hub, address spoke) external;
    220
    221
      /// @notice Updates the interest rate data for an asset.
    222
      /// @param hub The address of the Hub contract.
    223
      /// @param assetId The identifier of the asset.
    224
      /// @param irData The interest rate data to apply to the given asset, encoded in bytes.
    225
      function updateInterestRateData(address hub, uint256 assetId, bytes calldata irData) external;
    226
    }
    227
    96.0% src/hub/libraries/AssetLogic.sol
    Lines covered: 97 / 101 (96.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.20;
    4
    5
    import {SafeCast} from 'src/dependencies/openzeppelin/SafeCast.sol';
    6
    import {MathUtils} from 'src/libraries/math/MathUtils.sol';
    7
    import {PercentageMath} from 'src/libraries/math/PercentageMath.sol';
    8
    import {WadRayMath} from 'src/libraries/math/WadRayMath.sol';
    9
    import {SharesMath} from 'src/hub/libraries/SharesMath.sol';
    10
    import {Premium} from 'src/hub/libraries/Premium.sol';
    11
    import {IBasicInterestRateStrategy} from 'src/hub/interfaces/IBasicInterestRateStrategy.sol';
    12
    import {IHub} from 'src/hub/interfaces/IHub.sol';
    13
    14
    /// @title AssetLogic library
    15
    /// @author Aave Labs
    16
    /// @notice Implements the base logic and share price conversions for asset data.
    17
    library AssetLogic {
    18
      using AssetLogic for IHub.Asset;
    19
      using SafeCast for uint256;
    20
      using MathUtils for uint256;
    21
      using PercentageMath for uint256;
    22
      using WadRayMath for *;
    23
      using SharesMath for uint256;
    24
    25
      /// @notice Converts an amount of shares to the equivalent amount of drawn assets, rounding up.
    26
      function toDrawnAssetsUp(
    27
        IHub.Asset storage asset,
    28
        uint256 shares
    29
      ) internal view returns (uint256) {
    30
        return shares.rayMulUp(asset.getDrawnIndex());
    31
      }
    32
    33
      /// @notice Converts an amount of shares to the equivalent amount of drawn assets, rounding down.
    34
      function toDrawnAssetsDown(
    35
        IHub.Asset storage asset,
    36
        uint256 shares
    37
      ) internal view returns (uint256) {
    38
        return shares.rayMulDown(asset.getDrawnIndex());
    39
      }
    40
    41
      /// @notice Converts an amount of drawn assets to the equivalent amount of shares, rounding up.
    42
      function toDrawnSharesUp(
    43
        IHub.Asset storage asset,
    44
        uint256 assets
    45
      ) internal view returns (uint256) {
    46
        return assets.rayDivUp(asset.getDrawnIndex());
    47
      }
    48
    49
      /// @notice Converts an amount of drawn assets to the equivalent amount of shares, rounding down.
    50
      function toDrawnSharesDown(
    51
        IHub.Asset storage asset,
    52
        uint256 assets
    53
      ) internal view returns (uint256) {
    54
        return assets.rayDivDown(asset.getDrawnIndex());
    55
      }
    56
    57
      /// @notice Returns the total drawn assets amount for the specified asset.
    58
      function drawn(IHub.Asset storage asset, uint256 drawnIndex) internal view returns (uint256) {
    59
        return asset.drawnShares.rayMulUp(drawnIndex);
    60
      }
    61
    62
      /// @notice Returns the total premium amount for the specified asset.
    63
      function premium(IHub.Asset storage asset, uint256 drawnIndex) internal view returns (uint256) {
    64
        return
    65
          Premium
    66
            .calculatePremiumRay({
    67
              premiumShares: asset.premiumShares,
    68
              drawnIndex: drawnIndex,
    69
              premiumOffsetRay: asset.premiumOffsetRay
    70
            })
    71
            .fromRayUp();
    72
      }
    73
    74
      /// @notice Returns the total amount owed for the specified asset, including drawn and premium.
    75
      function totalOwed(IHub.Asset storage asset, uint256 drawnIndex) internal view returns (uint256) {
    76
        return asset.drawn(drawnIndex) + asset.premium(drawnIndex);
    77
      }
    78
    79
      /// @notice Returns the total added assets for the specified asset.
    80
      function totalAddedAssets(IHub.Asset storage asset) internal view returns (uint256) {
    81
        uint256 drawnIndex = asset.getDrawnIndex();
    82
    83
        uint256 aggregatedOwedRay = _calculateAggregatedOwedRay({
    84
          drawnShares: asset.drawnShares,
    85
          premiumShares: asset.premiumShares,
    86
          premiumOffsetRay: asset.premiumOffsetRay,
    87
          deficitRay: asset.deficitRay,
    88
          drawnIndex: drawnIndex
    89
        });
    90
    91
        return
    92
          asset.liquidity +
    93
          asset.swept +
    94
          aggregatedOwedRay.fromRayUp() -
    95
          asset.realizedFees -
    96
          asset.getUnrealizedFees(drawnIndex);
    97
      }
    98
    99
      /// @notice Converts an amount of shares to the equivalent amount of added assets, rounding up.
    100
      function toAddedAssetsUp(
    101
        IHub.Asset storage asset,
    102
        uint256 shares
    103
      ) internal view returns (uint256) {
    104
        return shares.toAssetsUp(asset.totalAddedAssets(), asset.addedShares);
    105
      }
    106
    107
      /// @notice Converts an amount of shares to the equivalent amount of added assets, rounding down.
    108
      function toAddedAssetsDown(
    109
        IHub.Asset storage asset,
    110
        uint256 shares
    111
      ) internal view returns (uint256) {
    112
        return shares.toAssetsDown(asset.totalAddedAssets(), asset.addedShares);
    113
      }
    114
    115
      /// @notice Converts an amount of added assets to the equivalent amount of shares, rounding up.
    116
      function toAddedSharesUp(
    117
        IHub.Asset storage asset,
    118
        uint256 assets
    119
      ) internal view returns (uint256) {
    120
        return assets.toSharesUp(asset.totalAddedAssets(), asset.addedShares);
    121
      }
    122
    123
      /// @notice Converts an amount of added assets to the equivalent amount of shares, rounding down.
    124
      function toAddedSharesDown(
    125
        IHub.Asset storage asset,
    126
        uint256 assets
    127
      ) internal view returns (uint256) {
    128
        return assets.toSharesDown(asset.totalAddedAssets(), asset.addedShares);
    129
      }
    130
    131
      /// @notice Updates the drawn rate of a specified asset.
    132
      /// @dev Premium debt is not used in the interest rate calculation.
    133
      /// @dev Uses last stored index; asset accrual should have already occurred.
    134
      /// @dev Imprecision from downscaling `deficitRay` does not accumulate.
    135
      function updateDrawnRate(IHub.Asset storage asset, uint256 assetId) internal {
    136
        uint256 drawnIndex = asset.drawnIndex;
    137
        uint256 newDrawnRate = IBasicInterestRateStrategy(asset.irStrategy).calculateInterestRate({
    138
          assetId: assetId,
    139
          liquidity: asset.liquidity,
    140
          drawn: asset.drawn(drawnIndex),
    141
          deficit: asset.deficitRay.fromRayUp(),
    142
          swept: asset.swept
    143
        });
    144
        asset.drawnRate = newDrawnRate.toUint96();
    145
    146
        emit IHub.UpdateAsset(assetId, drawnIndex, newDrawnRate, asset.realizedFees);
    147
      }
    148
    149
      /// @notice Accrues interest and fees for the specified asset.
    150
      function accrue(IHub.Asset storage asset) internal {
    151
        if (asset.lastUpdateTimestamp == block.timestamp) {
    152
          return;
    153
        }
    154
    155
        uint256 drawnIndex = asset.getDrawnIndex();
    156
        asset.realizedFees += asset.getUnrealizedFees(drawnIndex).toUint120();
    157
        asset.drawnIndex = drawnIndex.toUint120();
    158
        asset.lastUpdateTimestamp = block.timestamp.toUint40();
    159
      }
    160
    161
      /// @notice Calculates the drawn index of a specified asset based on the existing drawn rate and index.
    162
      function getDrawnIndex(IHub.Asset storage asset) internal view returns (uint256) {
    163
        uint256 previousIndex = asset.drawnIndex;
    164
        uint40 lastUpdateTimestamp = asset.lastUpdateTimestamp;
    165
        if (
    166
          lastUpdateTimestamp == block.timestamp || (asset.drawnShares == 0 && asset.premiumShares == 0)
    167
        ) {
    168
          return previousIndex;
    169
        }
    170
        return
    171
          previousIndex.rayMulUp(
    172
            MathUtils.calculateLinearInterest(asset.drawnRate, lastUpdateTimestamp)
    173
          );
    174
      }
    175
    176
      /// @notice Calculates the amount of fees derived from the index growth due to interest accrual.
    177
      /// @param drawnIndex The current drawn index.
    178
      function getUnrealizedFees(
    179
        IHub.Asset storage asset,
    180
        uint256 drawnIndex
    181
      ) internal view returns (uint256) {
    182
        uint256 previousIndex = asset.drawnIndex;
    183
        if (previousIndex == drawnIndex) {
    184
          return 0;
    185
        }
    186
    187
        uint256 liquidityFee = asset.liquidityFee;
    188
        if (liquidityFee == 0) {
    189
          return 0;
    190
        }
    191
    192
        uint120 drawnShares = asset.drawnShares;
    193
        uint120 premiumShares = asset.premiumShares;
    194
        int256 premiumOffsetRay = asset.premiumOffsetRay;
    195
        uint256 deficitRay = asset.deficitRay;
    196
    197
        uint256 aggregatedOwedRayAfter = _calculateAggregatedOwedRay({
    198
          drawnShares: drawnShares,
    199
          premiumShares: premiumShares,
    200
          premiumOffsetRay: premiumOffsetRay,
    201
          deficitRay: deficitRay,
    202
          drawnIndex: drawnIndex
    203
        });
    204
    205
        uint256 aggregatedOwedRayBefore = _calculateAggregatedOwedRay({
    206
          drawnShares: drawnShares,
    207
          premiumShares: premiumShares,
    208
          premiumOffsetRay: premiumOffsetRay,
    209
          deficitRay: deficitRay,
    210
          drawnIndex: previousIndex
    211
        });
    212
    213
        return
    214
          (aggregatedOwedRayAfter.fromRayUp() - aggregatedOwedRayBefore.fromRayUp()).percentMulDown(
    215
            liquidityFee
    216
          );
    217
      }
    218
    219
      /// @notice Calculates the aggregated owed amount for a specified asset, expressed in asset units and scaled by RAY.
    220
      function _calculateAggregatedOwedRay(
    221
        uint256 drawnShares,
    222
        uint256 premiumShares,
    223
        int256 premiumOffsetRay,
    224
        uint256 deficitRay,
    225
        uint256 drawnIndex
    226
      ) internal pure returns (uint256) {
    227
        uint256 premiumRay = Premium.calculatePremiumRay({
    228
          premiumShares: premiumShares,
    229
          premiumOffsetRay: premiumOffsetRay,
    230
          drawnIndex: drawnIndex
    231
        });
    232
        return (drawnShares * drawnIndex) + premiumRay + deficitRay;
    233
      }
    234
    }
    235
    100.0% src/hub/libraries/Premium.sol
    Lines covered: 4 / 4 (100.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.20;
    4
    5
    import {SafeCast} from 'src/dependencies/openzeppelin/SafeCast.sol';
    6
    7
    /// @title Premium library
    8
    /// @author Aave Labs
    9
    /// @notice Implements the premium calculations.
    10
    library Premium {
    11
      using SafeCast for *;
    12
    13
      /// @notice Calculates the premium debt with full precision.
    14
      /// @param premiumShares The number of premium shares.
    15
      /// @param premiumOffsetRay The premium offset, expressed in asset units and scaled by RAY.
    16
      /// @param drawnIndex The current drawn index.
    17
      /// @return The premium debt, expressed in asset units and scaled by RAY.
    18
      function calculatePremiumRay(
    19
        uint256 premiumShares,
    20
        int256 premiumOffsetRay,
    21
        uint256 drawnIndex
    22
      ) internal pure returns (uint256) {
    23
        return ((premiumShares * drawnIndex).toInt256() - premiumOffsetRay).toUint256();
    24
      }
    25
    }
    26
    100.0% src/hub/libraries/SharesMath.sol
    Lines covered: 15 / 15 (100.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.20;
    4
    5
    import {MathUtils} from 'src/libraries/math/MathUtils.sol';
    6
    7
    /// @title SharesMath library
    8
    /// @author Aave Labs
    9
    /// @notice Implements the logic to convert between assets and shares.
    10
    /// @dev Utilizes virtual assets and shares to mitigate share manipulation attacks.
    11
    library SharesMath {
    12
      using MathUtils for uint256;
    13
    14
      uint256 internal constant VIRTUAL_ASSETS = 1e6;
    15
      uint256 internal constant VIRTUAL_SHARES = 1e6;
    16
    17
      /// @notice Converts an amount of assets to the equivalent amount of shares, rounding down.
    18
      function toSharesDown(
    19
        uint256 assets,
    20
        uint256 totalAssets,
    21
        uint256 totalShares
    22
      ) internal pure returns (uint256) {
    23
        return assets.mulDivDown(totalShares + VIRTUAL_SHARES, totalAssets + VIRTUAL_ASSETS);
    24
      }
    25
    26
      /// @notice Converts an amount of shares to the equivalent amount of assets, rounding down.
    27
      function toAssetsDown(
    28
        uint256 shares,
    29
        uint256 totalAssets,
    30
        uint256 totalShares
    31
      ) internal pure returns (uint256) {
    32
        return shares.mulDivDown(totalAssets + VIRTUAL_ASSETS, totalShares + VIRTUAL_SHARES);
    33
      }
    34
    35
      /// @notice Converts an amount of assets to the equivalent amount of shares, rounding up.
    36
      function toSharesUp(
    37
        uint256 assets,
    38
        uint256 totalAssets,
    39
        uint256 totalShares
    40
      ) internal pure returns (uint256) {
    41
        return assets.mulDivUp(totalShares + VIRTUAL_SHARES, totalAssets + VIRTUAL_ASSETS);
    42
      }
    43
    44
      /// @notice Converts an amount of shares to the equivalent amount of assets, rounding up.
    45
      function toAssetsUp(
    46
        uint256 shares,
    47
        uint256 totalAssets,
    48
        uint256 totalShares
    49
      ) internal pure returns (uint256) {
    50
        return shares.mulDivUp(totalAssets + VIRTUAL_ASSETS, totalShares + VIRTUAL_SHARES);
    51
      }
    52
    }
    53
    0.0% src/interfaces/IMulticall.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    /// @title IMulticall
    6
    /// @author Aave Labs
    7
    /// @notice Minimal interface for Multicall.
    8
    interface IMulticall {
    9
      /// @notice Call multiple functions in the current contract and return the data from each if they all succeed.
    10
      /// @param data The encoded function data for each of the calls to make to this contract.
    11
      /// @return results The results from each of the calls passed in via data.
    12
      function multicall(bytes[] calldata data) external returns (bytes[] memory);
    13
    }
    14
    0.0% src/interfaces/INoncesKeyed.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    interface INoncesKeyed {
    6
      /// @notice Thrown when nonce being consumed does not match `currentNonce` for `account`.
    7
      error InvalidAccountNonce(address account, uint256 currentNonce);
    8
    9
      /// @notice Allows caller to revoke their next sequential nonce at specified `key`.
    10
      /// @dev This does not invalidate nonce at other `key`s namespace.
    11
      /// @param key The key which specifies namespace of the nonce.
    12
      /// @return keyNonce The revoked key-prefixed nonce.
    13
      function useNonce(uint192 key) external returns (uint256 keyNonce);
    14
    15
      /// @notice Returns the next unused nonce for an address and key. Result contains the key prefix.
    16
      /// @param owner The address of the nonce over.
    17
      /// @param key The key which specifies namespace of the nonce.
    18
      /// @return keyNonce The first 24 bytes are for the key, & the last 8 bytes for the nonce.
    19
      function nonces(address owner, uint192 key) external view returns (uint256 keyNonce);
    20
    }
    21
    0.0% src/interfaces/IRescuable.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    /// @title IRescuable
    6
    /// @author Aave Labs
    7
    /// @notice Interface for Rescuable.
    8
    interface IRescuable {
    9
      /// @notice Thrown when caller is not the rescue guardian.
    10
      error OnlyRescueGuardian();
    11
    12
      /// @notice Recovers ERC20 tokens sent to this contract.
    13
      /// @param token The address of the ERC20 token to rescue.
    14
      /// @param to The address to send the rescued tokens to.
    15
      /// @param amount Amount of tokens to rescue.
    16
      function rescueToken(address token, address to, uint256 amount) external;
    17
    18
      /// @notice Recovers native assets remaining in this contract.
    19
      /// @param to The address to send rescued native assets to.
    20
      /// @param amount Amount of native assets to rescue.
    21
      function rescueNative(address to, uint256 amount) external;
    22
    23
      /// @notice Returns the rescue guardian address.
    24
      /// @return The address allowed to rescue funds.
    25
      function rescueGuardian() external view returns (address);
    26
    }
    27
    87.0% src/libraries/math/MathUtils.sol
    Lines covered: 27 / 31 (87.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.20;
    4
    5
    /// @title MathUtils library
    6
    /// @author Aave Labs
    7
    library MathUtils {
    8
      uint256 internal constant RAY = 1e27;
    9
      /// @dev Ignoring leap years
    10
      uint256 internal constant SECONDS_PER_YEAR = 365 days;
    11
    12
      /// @notice Calculates the interest accumulated using a linear interest rate formula.
    13
      /// @dev Reverts if `lastUpdateTimestamp` is greater than `block.timestamp`.
    14
      /// @param rate The interest rate in RAY units.
    15
      /// @param lastUpdateTimestamp The timestamp to calculate interest rate from.
    16
      /// @return result The interest rate linearly accumulated during the time delta in RAY units.
    17
      function calculateLinearInterest(
    18
        uint96 rate,
    19
        uint40 lastUpdateTimestamp
    20
      ) internal view returns (uint256 result) {
    21
        assembly ('memory-safe') {
    22
          if gt(lastUpdateTimestamp, timestamp()) {
    23
            revert(0, 0)
    24
          }
    25
          result := sub(timestamp(), lastUpdateTimestamp)
    26
          result := add(div(mul(rate, result), SECONDS_PER_YEAR), RAY)
    27
        }
    28
      }
    29
    30
      /// @notice Returns the smaller of two unsigned integers.
    31
      function min(uint256 a, uint256 b) internal pure returns (uint256 result) {
    32
        assembly ('memory-safe') {
    33
          result := xor(b, mul(xor(a, b), lt(a, b)))
    34
        }
    35
      }
    36
    37
      /// @notice Returns the sum of an unsigned and signed integer.
    38
      /// @dev Reverts on underflow.
    39
      function add(uint256 a, int256 b) internal pure returns (uint256) {
    40
        if (b >= 0) return a + uint256(b);
    41
        return a - uint256(-b);
    42
      }
    43
    44
      /// @notice Returns the sum of two unsigned integers.
    45
      /// @dev Does not revert on overflow.
    46
      function uncheckedAdd(uint256 a, uint256 b) internal pure returns (uint256) {
    47
        unchecked {
    48
          return a + b;
    49
        }
    50
      }
    51
    52
      /// @notice Returns the difference of two unsigned integers as a signed integer.
    53
      /// @dev Does not ensure the `a` and `b` values are within the range of a signed integer.
    54
      function signedSub(uint256 a, uint256 b) internal pure returns (int256) {
    55
        return int256(a) - int256(b);
    56
      }
    57
    58
      /// @notice Returns the difference of two unsigned integers.
    59
      /// @dev Does not revert on underflow.
    60
      function uncheckedSub(uint256 a, uint256 b) internal pure returns (uint256) {
    61
        unchecked {
    62
          return a - b;
    63
        }
    64
      }
    65
    66
      /// @notice Raises an unsigned integer to the power of an unsigned integer.
    67
      /// @dev Does not revert on overflow.
    68
      function uncheckedExp(uint256 a, uint256 b) internal pure returns (uint256) {
    69
        unchecked {
    70
          return a ** b;
    71
        }
    72
      }
    73
    74
      /// @notice Multiplies `a` and `b` in 256 bits and divides the result by `c`, rounding down.
    75
      /// @dev Reverts if division by zero or overflow occurs on intermediate multiplication.
    76
      /// @return d = floor(a * b / c).
    77
      function mulDivDown(uint256 a, uint256 b, uint256 c) internal pure returns (uint256 d) {
    78
        // to avoid overflow, a <= type(uint256).max / b
    79
        assembly ('memory-safe') {
    80
          if iszero(c) {
    81
            revert(0, 0)
    82
          }
    83
          if iszero(or(iszero(b), iszero(gt(a, div(not(0), b))))) {
    84
            revert(0, 0)
    85
          }
    86
          d := div(mul(a, b), c)
    87
        }
    88
      }
    89
    90
      /// @notice Multiplies `a` and `b` in 256 bits and divides the result by `c`, rounding up.
    91
      /// @dev Reverts if division by zero or overflow occurs on intermediate multiplication.
    92
      /// @return d = ceil(a * b / c).
    93
      function mulDivUp(uint256 a, uint256 b, uint256 c) internal pure returns (uint256 d) {
    94
        // to avoid overflow, a <= type(uint256).max / b
    95
        assembly ('memory-safe') {
    96
          if iszero(c) {
    97
            revert(0, 0)
    98
          }
    99
          if iszero(or(iszero(b), iszero(gt(a, div(not(0), b))))) {
    100
            revert(0, 0)
    101
          }
    102
          d := mul(a, b)
    103
          // add 1 if (a * b) % c > 0 to round up the division of (a * b) by c
    104
          d := add(div(d, c), gt(mod(d, c), 0))
    105
        }
    106
      }
    107
    }
    108
    85.0% src/libraries/math/PercentageMath.sol
    Lines covered: 12 / 14 (85.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.20;
    4
    5
    /// @title PercentageMath library
    6
    /// @author Aave Labs
    7
    /// @notice Provides functions to perform percentage calculations with explicit rounding.
    8
    /// @dev Percentages are defined by default with 2 decimals of precision (100.00). The precision is indicated by `PERCENTAGE_FACTOR`.
    9
    library PercentageMath {
    10
      // Maximum percentage factor in BPS (100.00%)
    11
      uint256 internal constant PERCENTAGE_FACTOR = 1e4;
    12
    13
      /// @notice Executes a percentage multiplication, rounded down.
    14
      /// @dev Reverts if intermediate multiplication overflows.
    15
      /// @return result = floor(value * percentage / PERCENTAGE_FACTOR)
    16
      function percentMulDown(
    17
        uint256 value,
    18
        uint256 percentage
    19
      ) internal pure returns (uint256 result) {
    20
        // to avoid overflow, value <= type(uint256).max / percentage
    21
        assembly ('memory-safe') {
    22
          if iszero(or(iszero(percentage), iszero(gt(value, div(not(0), percentage))))) {
    23
            revert(0, 0)
    24
          }
    25
    26
          result := div(mul(value, percentage), PERCENTAGE_FACTOR)
    27
        }
    28
      }
    29
    30
      /// @notice Executes a percentage multiplication, rounded up.
    31
      /// @dev Reverts if intermediate multiplication overflows.
    32
      /// @return result = ceil(value * percentage / PERCENTAGE_FACTOR)
    33
      function percentMulUp(uint256 value, uint256 percentage) internal pure returns (uint256 result) {
    34
        // to avoid overflow, value <= type(uint256).max / percentage
    35
        assembly ('memory-safe') {
    36
          if iszero(or(iszero(percentage), iszero(gt(value, div(not(0), percentage))))) {
    37
            revert(0, 0)
    38
          }
    39
          result := mul(value, percentage)
    40
    41
          // Add 1 if (value * percentage) % PERCENTAGE_FACTOR > 0 to round up the division of (value * percentage) by PERCENTAGE_FACTOR
    42
          result := add(div(result, PERCENTAGE_FACTOR), gt(mod(result, PERCENTAGE_FACTOR), 0))
    43
        }
    44
      }
    45
    46
      /// @notice Executes a percentage division, rounded down.
    47
      /// @dev Reverts if division by zero or intermediate multiplication overflows.
    48
      /// @return result = floor(value * PERCENTAGE_FACTOR / percentage)
    49
      function percentDivDown(
    50
        uint256 value,
    51
        uint256 percentage
    52
      ) internal pure returns (uint256 result) {
    53
        // to avoid overflow, value <= type(uint256).max / PERCENTAGE_FACTOR
    54
        assembly ('memory-safe') {
    55
          if or(iszero(percentage), iszero(iszero(gt(value, div(not(0), PERCENTAGE_FACTOR))))) {
    56
            revert(0, 0)
    57
          }
    58
    59
          result := div(mul(value, PERCENTAGE_FACTOR), percentage)
    60
        }
    61
      }
    62
    63
      /// @notice Executes a percentage division, rounded up.
    64
      /// @dev Reverts if division by zero or intermediate multiplication overflows.
    65
      /// @return result = ceil(value * PERCENTAGE_FACTOR / percentage)
    66
      function percentDivUp(uint256 value, uint256 percentage) internal pure returns (uint256 result) {
    67
        // to avoid overflow, value <= type(uint256).max / PERCENTAGE_FACTOR
    68
        assembly ('memory-safe') {
    69
          if or(iszero(percentage), iszero(iszero(gt(value, div(not(0), PERCENTAGE_FACTOR))))) {
    70
            revert(0, 0)
    71
          }
    72
          result := mul(value, PERCENTAGE_FACTOR)
    73
    74
          // Add 1 if (value * PERCENTAGE_FACTOR) % percentage > 0 to round up the division of (value * PERCENTAGE_FACTOR) by percentage
    75
          result := add(div(result, percentage), gt(mod(result, percentage), 0))
    76
        }
    77
      }
    78
    79
      /// @notice Truncates number from BPS precision, rounding down.
    80
      function fromBpsDown(uint256 value) internal pure returns (uint256) {
    81
        return value / PERCENTAGE_FACTOR;
    82
      }
    83
    }
    84
    73.0% src/libraries/math/WadRayMath.sol
    Lines covered: 36 / 49 (73.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.20;
    4
    5
    /// @title WadRayMath library
    6
    /// @author Aave Labs
    7
    /// @notice Provides utility functions to work with WAD and RAY units with explicit rounding.
    8
    library WadRayMath {
    9
      uint256 internal constant WAD = 1e18;
    10
      uint256 internal constant RAY = 1e27;
    11
      uint256 internal constant PERCENTAGE_FACTOR = 1e4;
    12
    13
      /// @notice Multiplies two WAD numbers, rounding down.
    14
      /// @dev Reverts if intermediate multiplication overflows.
    15
      /// @return c = floor(a * b / WAD) in WAD units.
    16
      function wadMulDown(uint256 a, uint256 b) internal pure returns (uint256 c) {
    17
        assembly ('memory-safe') {
    18
          // to avoid overflow, a <= type(uint256).max / b
    19
          if iszero(or(iszero(b), iszero(gt(a, div(not(0), b))))) {
    20
            revert(0, 0)
    21
          }
    22
    23
          c := div(mul(a, b), WAD)
    24
        }
    25
      }
    26
    27
      /// @notice Multiplies two WAD numbers, rounding up.
    28
      /// @dev Reverts if intermediate multiplication overflows.
    29
      /// @return c = ceil(a * b / WAD) in WAD units.
    30
      function wadMulUp(uint256 a, uint256 b) internal pure returns (uint256 c) {
    31
        assembly ('memory-safe') {
    32
          // to avoid overflow, a <= type(uint256).max / b
    33
          if iszero(or(iszero(b), iszero(gt(a, div(not(0), b))))) {
    34
            revert(0, 0)
    35
          }
    36
          c := mul(a, b)
    37
          // Add 1 if (a * b) % WAD > 0 to round up the division of (a * b) by WAD
    38
          c := add(div(c, WAD), gt(mod(c, WAD), 0))
    39
        }
    40
      }
    41
    42
      /// @notice Divides two WAD numbers, rounding down.
    43
      /// @dev Reverts if division by zero or intermediate multiplication overflows.
    44
      /// @return c = floor(a * WAD / b) in WAD units.
    45
      function wadDivDown(uint256 a, uint256 b) internal pure returns (uint256 c) {
    46
        assembly ('memory-safe') {
    47
          // to avoid overflow, a <= type(uint256).max / WAD
    48
          if or(iszero(b), iszero(iszero(gt(a, div(not(0), WAD))))) {
    49
            revert(0, 0)
    50
          }
    51
    52
          c := div(mul(a, WAD), b)
    53
        }
    54
      }
    55
    56
      /// @notice Divides two WAD numbers, rounding up.
    57
      /// @dev Reverts if division by zero or intermediate multiplication overflows.
    58
      /// @return c = ceil(a * WAD / b) in WAD units.
    59
      function wadDivUp(uint256 a, uint256 b) internal pure returns (uint256 c) {
    60
        assembly ('memory-safe') {
    61
          // to avoid overflow, a <= type(uint256).max / WAD
    62
          if or(iszero(b), iszero(iszero(gt(a, div(not(0), WAD))))) {
    63
            revert(0, 0)
    64
          }
    65
          c := mul(a, WAD)
    66
          // Add 1 if (a * WAD) % b > 0 to round up the division of (a * WAD) by b
    67
          c := add(div(c, b), gt(mod(c, b), 0))
    68
        }
    69
      }
    70
    71
      /// @notice Multiplies two RAY numbers, rounding down.
    72
      /// @dev Reverts if intermediate multiplication overflows.
    73
      /// @return c = floor(a * b / RAY) in RAY units.
    74
      function rayMulDown(uint256 a, uint256 b) internal pure returns (uint256 c) {
    75
        assembly ('memory-safe') {
    76
          // to avoid overflow, a <= type(uint256).max / b
    77
          if iszero(or(iszero(b), iszero(gt(a, div(not(0), b))))) {
    78
            revert(0, 0)
    79
          }
    80
    81
          c := div(mul(a, b), RAY)
    82
        }
    83
      }
    84
    85
      /// @notice Multiplies two RAY numbers, rounding up.
    86
      /// @dev Reverts if intermediate multiplication overflows.
    87
      /// @return c = ceil(a * b / RAY) in RAY units.
    88
      function rayMulUp(uint256 a, uint256 b) internal pure returns (uint256 c) {
    89
        assembly ('memory-safe') {
    90
          // to avoid overflow, a <= type(uint256).max / b
    91
          if iszero(or(iszero(b), iszero(gt(a, div(not(0), b))))) {
    92
            revert(0, 0)
    93
          }
    94
          c := mul(a, b)
    95
          // Add 1 if (a * b) % RAY > 0 to round up the division of (a * b) by RAY
    96
          c := add(div(c, RAY), gt(mod(c, RAY), 0))
    97
        }
    98
      }
    99
    100
      /// @notice Divides two RAY numbers, rounding down.
    101
      /// @dev Reverts if division by zero or intermediate multiplication overflows.
    102
      /// @return c = floor(a * RAY / b) in RAY units.
    103
      function rayDivDown(uint256 a, uint256 b) internal pure returns (uint256 c) {
    104
        assembly ('memory-safe') {
    105
          // to avoid overflow, a <= type(uint256).max / RAY
    106
          if or(iszero(b), iszero(iszero(gt(a, div(not(0), RAY))))) {
    107
            revert(0, 0)
    108
          }
    109
    110
          c := div(mul(a, RAY), b)
    111
        }
    112
      }
    113
    114
      /// @notice Divides two RAY numbers, rounding up.
    115
      /// @dev Reverts if division by zero or intermediate multiplication overflows.
    116
      /// @return c = ceil(a * RAY / b) in RAY units.
    117
      function rayDivUp(uint256 a, uint256 b) internal pure returns (uint256 c) {
    118
        assembly ('memory-safe') {
    119
          // to avoid overflow, a <= type(uint256).max / RAY
    120
          if or(iszero(b), iszero(iszero(gt(a, div(not(0), RAY))))) {
    121
            revert(0, 0)
    122
          }
    123
          c := mul(a, RAY)
    124
          // Add 1 if (a * RAY) % b > 0 to round up the division of (a * RAY) by b
    125
          c := add(div(c, b), gt(mod(c, b), 0))
    126
        }
    127
      }
    128
    129
      /// @notice Casts value to WAD, adding 18 digits of precision.
    130
      /// @dev Reverts if intermediate multiplication overflows.
    131
      /// @return b = a * WAD in WAD units.
    132
      function toWad(uint256 a) internal pure returns (uint256 b) {
    133
        assembly ('memory-safe') {
    134
          b := mul(a, WAD)
    135
    136
          // to avoid overflow, b/WAD == a
    137
          if iszero(eq(div(b, WAD), a)) {
    138
            revert(0, 0)
    139
          }
    140
        }
    141
      }
    142
    143
      /// @notice Casts value to RAY, adding 27 digits of precision.
    144
      /// @dev Reverts if intermediate multiplication overflows.
    145
      /// @return b = a * RAY in RAY units.
    146
      function toRay(uint256 a) internal pure returns (uint256 b) {
    147
        assembly ('memory-safe') {
    148
          b := mul(a, RAY)
    149
    150
          // to avoid overflow, b/RAY == a
    151
          if iszero(eq(div(b, RAY), a)) {
    152
            revert(0, 0)
    153
          }
    154
        }
    155
      }
    156
    157
      /// @notice Removes WAD precision from a given value, rounding down.
    158
      /// @return b = a / WAD.
    159
      function fromWadDown(uint256 a) internal pure returns (uint256 b) {
    160
        assembly ('memory-safe') {
    161
          b := div(a, WAD)
    162
        }
    163
      }
    164
    165
      /// @notice Removes RAY precision from a given value, rounding up.
    166
      /// @return b = ceil(a / RAY).
    167
      function fromRayUp(uint256 a) internal pure returns (uint256 b) {
    168
        assembly ('memory-safe') {
    169
          // add 1 if (a % RAY) > 0 to round up the division of a by RAY
    170
          b := add(div(a, RAY), gt(mod(a, RAY), 0))
    171
        }
    172
      }
    173
    174
      /// @notice Converts value from basis points to WAD, rounding down.
    175
      /// @dev Reverts if intermediate multiplication overflows.
    176
      /// @return b = floor(a * WAD / PERCENTAGE_FACTOR) in WAD units.
    177
      function bpsToWad(uint256 a) internal pure returns (uint256 b) {
    178
        assembly ('memory-safe') {
    179
          b := mul(a, WAD)
    180
    181
          // to avoid overflow, b/WAD == a
    182
          if iszero(eq(div(b, WAD), a)) {
    183
            revert(0, 0)
    184
          }
    185
    186
          b := div(b, PERCENTAGE_FACTOR)
    187
        }
    188
      }
    189
    190
      /// @notice Converts value from basis points to RAY, rounding down.
    191
      /// @dev Reverts if intermediate multiplication overflows.
    192
      /// @return b = a * RAY / PERCENTAGE_FACTOR in RAY units.
    193
      function bpsToRay(uint256 a) internal pure returns (uint256 b) {
    194
        assembly ('memory-safe') {
    195
          b := mul(a, RAY)
    196
    197
          // to avoid overflow, b/RAY == a
    198
          if iszero(eq(div(b, RAY), a)) {
    199
            revert(0, 0)
    200
          }
    201
    202
          b := div(b, PERCENTAGE_FACTOR)
    203
        }
    204
      }
    205
    }
    206
    100.0% src/libraries/types/EIP712Types.sol
    Lines covered: 1 / 1 (100.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.20;
    4
    5
    /// @title EIP712Types library
    6
    /// @author Aave Labs
    7
    /// @notice Defines type structs used in EIP712-typed signatures.
    8
    library EIP712Types {
    9
      struct SetUserPositionManager {
    10
        address positionManager;
    11
        address user;
    12
        bool approve;
    13
        uint256 nonce;
    14
        uint256 deadline;
    15
      }
    16
    17
      struct Permit {
    18
        address owner;
    19
        address spender;
    20
        uint256 value;
    21
        uint256 nonce;
    22
        uint256 deadline;
    23
      }
    24
    25
      struct Supply {
    26
        address spoke;
    27
        uint256 reserveId;
    28
        uint256 amount;
    29
        address onBehalfOf;
    30
        uint256 nonce;
    31
        uint256 deadline;
    32
      }
    33
    34
      struct Withdraw {
    35
        address spoke;
    36
        uint256 reserveId;
    37
        uint256 amount;
    38
        address onBehalfOf;
    39
        uint256 nonce;
    40
        uint256 deadline;
    41
      }
    42
    43
      struct Borrow {
    44
        address spoke;
    45
        uint256 reserveId;
    46
        uint256 amount;
    47
        address onBehalfOf;
    48
        uint256 nonce;
    49
        uint256 deadline;
    50
      }
    51
    52
      struct Repay {
    53
        address spoke;
    54
        uint256 reserveId;
    55
        uint256 amount;
    56
        address onBehalfOf;
    57
        uint256 nonce;
    58
        uint256 deadline;
    59
      }
    60
    61
      struct SetUsingAsCollateral {
    62
        address spoke;
    63
        uint256 reserveId;
    64
        bool useAsCollateral;
    65
        address onBehalfOf;
    66
        uint256 nonce;
    67
        uint256 deadline;
    68
      }
    69
    70
      struct UpdateUserRiskPremium {
    71
        address spoke;
    72
        address user;
    73
        uint256 nonce;
    74
        uint256 deadline;
    75
      }
    76
    77
      struct UpdateUserDynamicConfig {
    78
        address spoke;
    79
        address user;
    80
        uint256 nonce;
    81
        uint256 deadline;
    82
      }
    83
    }
    84
    80.0% src/libraries/types/Roles.sol
    Lines covered: 4 / 5 (80.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.20;
    4
    5
    /// @title Roles library
    6
    /// @author Aave Labs
    7
    /// @notice Defines the different roles used by the protocol.
    8
    library Roles {
    9
      uint64 public constant DEFAULT_ADMIN_ROLE = 0;
    10
      uint64 public constant HUB_ADMIN_ROLE = 1;
    11
      uint64 public constant SPOKE_ADMIN_ROLE = 2;
    12
      uint64 public constant USER_POSITION_UPDATER_ROLE = 3;
    13
    }
    14
    0.0% src/misc/UnitPriceFeed.sol
    Lines covered: 0 / 22 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity 0.8.28;
    4
    5
    import {AggregatorV3Interface} from 'src/dependencies/chainlink/AggregatorV3Interface.sol';
    6
    7
    /// @title UnitPriceFeed contract
    8
    /// @author Aave Labs
    9
    /// @notice Price feed that returns the unit price (1), with decimals precision.
    10
    /// @dev This price feed can be set for reserves that use the base currency as collateral.
    11
    contract UnitPriceFeed is AggregatorV3Interface {
    12
      /// @inheritdoc AggregatorV3Interface
    13
      uint8 public immutable decimals;
    14
    15
      /// @inheritdoc AggregatorV3Interface
    16
      string public description;
    17
    18
      int256 private immutable _units;
    19
    20
      /// @dev Constructor.
    21
      /// @param decimals_ The number of decimals used to represent the unit price.
    22
      /// @param description_ The description of the unit price feed.
    23
      constructor(uint8 decimals_, string memory description_) {
    24
        decimals = decimals_;
    25
        description = description_;
    26
        _units = int256(10 ** decimals_);
    27
      }
    28
    29
      /// @inheritdoc AggregatorV3Interface
    30
      function version() external pure returns (uint256) {
    31
        return 1;
    32
      }
    33
    34
      /// @inheritdoc AggregatorV3Interface
    35
      function getRoundData(
    36
        uint80 _roundId
    37
      )
    38
        external
    39
        view
    40
        returns (
    41
          uint80 roundId,
    42
          int256 answer,
    43
          uint256 startedAt,
    44
          uint256 updatedAt,
    45
          uint80 answeredInRound
    46
        )
    47
      {
    48
        if (_roundId <= uint80(block.timestamp)) {
    49
          roundId = _roundId;
    50
          answer = _units;
    51
          startedAt = _roundId;
    52
          updatedAt = _roundId;
    53
          answeredInRound = _roundId;
    54
        }
    55
      }
    56
    57
      /// @inheritdoc AggregatorV3Interface
    58
      function latestRoundData()
    59
        external
    60
        view
    61
        returns (
    62
          uint80 roundId,
    63
          int256 answer,
    64
          uint256 startedAt,
    65
          uint256 updatedAt,
    66
          uint80 answeredInRound
    67
        )
    68
      {
    69
        roundId = uint80(block.timestamp);
    70
        answer = _units;
    71
        startedAt = block.timestamp;
    72
        updatedAt = block.timestamp;
    73
        answeredInRound = roundId;
    74
      }
    75
    }
    76
    0.0% src/position-manager/GatewayBase.sol
    Lines covered: 0 / 17 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity 0.8.28;
    4
    5
    import {Ownable2Step, Ownable} from 'src/dependencies/openzeppelin/Ownable2Step.sol';
    6
    import {Rescuable} from 'src/utils/Rescuable.sol';
    7
    import {ISpoke} from 'src/spoke/interfaces/ISpoke.sol';
    8
    import {IGatewayBase} from 'src/position-manager/interfaces/IGatewayBase.sol';
    9
    10
    /// @title GatewayBase
    11
    /// @author Aave Labs
    12
    /// @notice Base implementation for gateway common functionalities.
    13
    abstract contract GatewayBase is IGatewayBase, Rescuable, Ownable2Step {
    14
      mapping(address => bool) internal _registeredSpokes;
    15
    16
      /// @notice Modifier that checks if the specified spoke is registered.
    17
      modifier onlyRegisteredSpoke(address spoke) {
    18
        _isSpokeValid(spoke);
    19
        _;
    20
      }
    21
    22
      /// @dev Constructor.
    23
      /// @param initialOwner_ The address of the initial owner.
    24
      constructor(address initialOwner_) Ownable(initialOwner_) {}
    25
    26
      /// @inheritdoc IGatewayBase
    27
      function registerSpoke(address spoke, bool active) external onlyOwner {
    28
        require(spoke != address(0), InvalidAddress());
    29
        _registeredSpokes[spoke] = active;
    30
        emit SpokeRegistered(spoke, active);
    31
      }
    32
    33
      /// @inheritdoc IGatewayBase
    34
      function renouncePositionManagerRole(address spoke, address user) external onlyOwner {
    35
        require(user != address(0), InvalidAddress());
    36
        ISpoke(spoke).renouncePositionManagerRole(user);
    37
      }
    38
    39
      /// @inheritdoc IGatewayBase
    40
      function isSpokeRegistered(address spoke) external view returns (bool) {
    41
        return _registeredSpokes[spoke];
    42
      }
    43
    44
      /// @dev Verifies the specified spoke is registered.
    45
      function _isSpokeValid(address spoke) internal view {
    46
        require(_registeredSpokes[spoke], SpokeNotRegistered());
    47
      }
    48
    49
      /// @return The underlying asset for `reserveId` on the specified spoke.
    50
      function _getReserveUnderlying(address spoke, uint256 reserveId) internal view returns (address) {
    51
        return ISpoke(spoke).getReserve(reserveId).underlying;
    52
      }
    53
    54
      /// @dev The `owner()` is the allowed caller for Rescuable methods.
    55
      function _rescueGuardian() internal view override returns (address) {
    56
        return owner();
    57
      }
    58
    }
    59
    0.0% src/position-manager/NativeTokenGateway.sol
    Lines covered: 0 / 70 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity 0.8.28;
    4
    5
    import {ReentrancyGuardTransient} from 'src/dependencies/openzeppelin/ReentrancyGuardTransient.sol';
    6
    import {Address} from 'src/dependencies/openzeppelin/Address.sol';
    7
    import {SafeERC20, IERC20} from 'src/dependencies/openzeppelin/SafeERC20.sol';
    8
    import {GatewayBase} from 'src/position-manager/GatewayBase.sol';
    9
    import {ISpoke} from 'src/spoke/interfaces/ISpoke.sol';
    10
    import {INativeWrapper} from 'src/position-manager/interfaces/INativeWrapper.sol';
    11
    import {INativeTokenGateway} from 'src/position-manager/interfaces/INativeTokenGateway.sol';
    12
    13
    /// @title NativeTokenGateway
    14
    /// @author Aave Labs
    15
    /// @notice Gateway to interact with a spoke using the native coin of a chain.
    16
    /// @dev Contract must be an active & approved user position manager in order to execute spoke actions on a user's behalf.
    17
    contract NativeTokenGateway is INativeTokenGateway, GatewayBase, ReentrancyGuardTransient {
    18
      using SafeERC20 for *;
    19
    20
      INativeWrapper internal immutable _nativeWrapper;
    21
    22
      /// @dev Constructor.
    23
      /// @param nativeWrapper_ The address of the native wrapper contract.
    24
      /// @param initialOwner_ The address of the initial owner.
    25
      constructor(address nativeWrapper_, address initialOwner_) GatewayBase(initialOwner_) {
    26
        require(nativeWrapper_ != address(0), InvalidAddress());
    27
        _nativeWrapper = INativeWrapper(payable(nativeWrapper_));
    28
      }
    29
    30
      /// @dev Checks only 'nativeWrapper' can transfer native tokens.
    31
      receive() external payable {
    32
        require(msg.sender == address(_nativeWrapper), UnsupportedAction());
    33
      }
    34
    35
      /// @dev Unsupported fallback function.
    36
      fallback() external payable {
    37
        revert UnsupportedAction();
    38
      }
    39
    40
      /// @inheritdoc INativeTokenGateway
    41
      function supplyNative(
    42
        address spoke,
    43
        uint256 reserveId,
    44
        uint256 amount
    45
      ) external payable nonReentrant onlyRegisteredSpoke(spoke) returns (uint256, uint256) {
    46
        require(msg.value == amount, NativeAmountMismatch());
    47
        return _supplyNative(spoke, reserveId, msg.sender, amount);
    48
      }
    49
    50
      /// @inheritdoc INativeTokenGateway
    51
      function supplyAsCollateralNative(
    52
        address spoke,
    53
        uint256 reserveId,
    54
        uint256 amount
    55
      ) external payable nonReentrant onlyRegisteredSpoke(spoke) returns (uint256, uint256) {
    56
        require(msg.value == amount, NativeAmountMismatch());
    57
        (uint256 suppliedShares, uint256 suppliedAmount) = _supplyNative(
    58
          spoke,
    59
          reserveId,
    60
          msg.sender,
    61
          amount
    62
        );
    63
        ISpoke(spoke).setUsingAsCollateral(reserveId, true, msg.sender);
    64
    65
        return (suppliedShares, suppliedAmount);
    66
      }
    67
    68
      /// @inheritdoc INativeTokenGateway
    69
      function withdrawNative(
    70
        address spoke,
    71
        uint256 reserveId,
    72
        uint256 amount
    73
      ) external onlyRegisteredSpoke(spoke) returns (uint256, uint256) {
    74
        address underlying = _getReserveUnderlying(spoke, reserveId);
    75
        _validateParams(underlying, amount);
    76
    77
        (uint256 withdrawnShares, uint256 withdrawnAmount) = ISpoke(spoke).withdraw(
    78
          reserveId,
    79
          amount,
    80
          msg.sender
    81
        );
    82
        _nativeWrapper.withdraw(withdrawnAmount);
    83
        Address.sendValue(payable(msg.sender), withdrawnAmount);
    84
    85
        return (withdrawnShares, withdrawnAmount);
    86
      }
    87
    88
      /// @inheritdoc INativeTokenGateway
    89
      function borrowNative(
    90
        address spoke,
    91
        uint256 reserveId,
    92
        uint256 amount
    93
      ) external onlyRegisteredSpoke(spoke) returns (uint256, uint256) {
    94
        address underlying = _getReserveUnderlying(spoke, reserveId);
    95
        _validateParams(underlying, amount);
    96
    97
        (uint256 borrowedShares, uint256 borrowedAmount) = ISpoke(spoke).borrow(
    98
          reserveId,
    99
          amount,
    100
          msg.sender
    101
        );
    102
        _nativeWrapper.withdraw(borrowedAmount);
    103
        Address.sendValue(payable(msg.sender), borrowedAmount);
    104
    105
        return (borrowedShares, borrowedAmount);
    106
      }
    107
    108
      /// @inheritdoc INativeTokenGateway
    109
      function repayNative(
    110
        address spoke,
    111
        uint256 reserveId,
    112
        uint256 amount
    113
      ) external payable nonReentrant onlyRegisteredSpoke(spoke) returns (uint256, uint256) {
    114
        require(msg.value == amount, NativeAmountMismatch());
    115
        address underlying = _getReserveUnderlying(spoke, reserveId);
    116
        _validateParams(underlying, amount);
    117
    118
        uint256 userTotalDebt = ISpoke(spoke).getUserTotalDebt(reserveId, msg.sender);
    119
        uint256 repayAmount = amount;
    120
        uint256 leftovers;
    121
        if (amount > userTotalDebt) {
    122
          leftovers = amount - userTotalDebt;
    123
          repayAmount = userTotalDebt;
    124
        }
    125
    126
        _nativeWrapper.deposit{value: repayAmount}();
    127
        _nativeWrapper.forceApprove(spoke, repayAmount);
    128
        (uint256 repaidShares, uint256 repaidAmount) = ISpoke(spoke).repay(
    129
          reserveId,
    130
          repayAmount,
    131
          msg.sender
    132
        );
    133
    134
        if (leftovers > 0) {
    135
          Address.sendValue(payable(msg.sender), leftovers);
    136
        }
    137
    138
        return (repaidShares, repaidAmount);
    139
      }
    140
    141
      /// @inheritdoc INativeTokenGateway
    142
      function NATIVE_WRAPPER() external view returns (address) {
    143
        return address(_nativeWrapper);
    144
      }
    145
    146
      /// @dev `msg.value` verification must be done before calling this.
    147
      function _supplyNative(
    148
        address spoke,
    149
        uint256 reserveId,
    150
        address user,
    151
        uint256 amount
    152
      ) internal returns (uint256, uint256) {
    153
        address underlying = _getReserveUnderlying(spoke, reserveId);
    154
        _validateParams(underlying, amount);
    155
    156
        _nativeWrapper.deposit{value: amount}();
    157
        _nativeWrapper.forceApprove(spoke, amount);
    158
        return ISpoke(spoke).supply(reserveId, amount, user);
    159
      }
    160
    161
      function _validateParams(address underlying, uint256 amount) internal view {
    162
        require(address(_nativeWrapper) == underlying, NotNativeWrappedAsset());
    163
        require(amount > 0, InvalidAmount());
    164
      }
    165
    }
    166
    0.0% src/position-manager/SignatureGateway.sol
    Lines covered: 0 / 111 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity 0.8.28;
    4
    5
    import {SignatureChecker} from 'src/dependencies/openzeppelin/SignatureChecker.sol';
    6
    import {SafeERC20, IERC20} from 'src/dependencies/openzeppelin/SafeERC20.sol';
    7
    import {IERC20Permit} from 'src/dependencies/openzeppelin/IERC20Permit.sol';
    8
    import {EIP712} from 'src/dependencies/solady/EIP712.sol';
    9
    import {MathUtils} from 'src/libraries/math/MathUtils.sol';
    10
    import {NoncesKeyed} from 'src/utils/NoncesKeyed.sol';
    11
    import {Multicall} from 'src/utils/Multicall.sol';
    12
    import {EIP712Hash, EIP712Types} from 'src/position-manager/libraries/EIP712Hash.sol';
    13
    import {GatewayBase} from 'src/position-manager/GatewayBase.sol';
    14
    import {ISpoke} from 'src/spoke/interfaces/ISpoke.sol';
    15
    import {ISignatureGateway} from 'src/position-manager/interfaces/ISignatureGateway.sol';
    16
    17
    /// @title SignatureGateway
    18
    /// @author Aave Labs
    19
    /// @notice Gateway to consume EIP-712 typed intents for spoke actions on behalf of a user.
    20
    /// @dev Contract must be an active & approved user position manager to execute spoke actions on user's behalf.
    21
    /// @dev Uses keyed-nonces where each key's namespace nonce is consumed sequentially. Intents bundled through
    22
    /// multicall can be executed independently in order of signed nonce & deadline; does not guarantee batch atomicity.
    23
    contract SignatureGateway is ISignatureGateway, GatewayBase, NoncesKeyed, Multicall, EIP712 {
    24
      using SafeERC20 for IERC20;
    25
      using EIP712Hash for *;
    26
    27
      /// @dev Constructor.
    28
      /// @param initialOwner_ The address of the initial owner.
    29
      constructor(address initialOwner_) GatewayBase(initialOwner_) {}
    30
    31
      /// @inheritdoc ISignatureGateway
    32
      function supplyWithSig(
    33
        EIP712Types.Supply calldata params,
    34
        bytes calldata signature
    35
      ) external onlyRegisteredSpoke(params.spoke) returns (uint256, uint256) {
    36
        require(block.timestamp <= params.deadline, InvalidSignature());
    37
        address spoke = params.spoke;
    38
        uint256 reserveId = params.reserveId;
    39
        address user = params.onBehalfOf;
    40
        bytes32 digest = _hashTypedData(params.hash());
    41
        require(SignatureChecker.isValidSignatureNow(user, digest, signature), InvalidSignature());
    42
        _useCheckedNonce(user, params.nonce);
    43
    44
        IERC20 underlying = IERC20(_getReserveUnderlying(spoke, reserveId));
    45
        underlying.safeTransferFrom(user, address(this), params.amount);
    46
        underlying.forceApprove(spoke, params.amount);
    47
    48
        return ISpoke(spoke).supply(reserveId, params.amount, user);
    49
      }
    50
    51
      /// @inheritdoc ISignatureGateway
    52
      function withdrawWithSig(
    53
        EIP712Types.Withdraw calldata params,
    54
        bytes calldata signature
    55
      ) external onlyRegisteredSpoke(params.spoke) returns (uint256, uint256) {
    56
        require(block.timestamp <= params.deadline, InvalidSignature());
    57
        address spoke = params.spoke;
    58
        uint256 reserveId = params.reserveId;
    59
        address user = params.onBehalfOf;
    60
        bytes32 digest = _hashTypedData(params.hash());
    61
        require(SignatureChecker.isValidSignatureNow(user, digest, signature), InvalidSignature());
    62
        _useCheckedNonce(user, params.nonce);
    63
    64
        IERC20 underlying = IERC20(_getReserveUnderlying(spoke, reserveId));
    65
        (uint256 withdrawnShares, uint256 withdrawnAmount) = ISpoke(spoke).withdraw(
    66
          reserveId,
    67
          params.amount,
    68
          user
    69
        );
    70
        underlying.safeTransfer(user, withdrawnAmount);
    71
    72
        return (withdrawnShares, withdrawnAmount);
    73
      }
    74
    75
      /// @inheritdoc ISignatureGateway
    76
      function borrowWithSig(
    77
        EIP712Types.Borrow calldata params,
    78
        bytes calldata signature
    79
      ) external onlyRegisteredSpoke(params.spoke) returns (uint256, uint256) {
    80
        require(block.timestamp <= params.deadline, InvalidSignature());
    81
        address spoke = params.spoke;
    82
        uint256 reserveId = params.reserveId;
    83
        address user = params.onBehalfOf;
    84
        bytes32 digest = _hashTypedData(params.hash());
    85
        require(SignatureChecker.isValidSignatureNow(user, digest, signature), InvalidSignature());
    86
        _useCheckedNonce(user, params.nonce);
    87
    88
        IERC20 underlying = IERC20(_getReserveUnderlying(spoke, reserveId));
    89
        (uint256 borrowedShares, uint256 borrowedAmount) = ISpoke(spoke).borrow(
    90
          reserveId,
    91
          params.amount,
    92
          user
    93
        );
    94
        underlying.safeTransfer(user, borrowedAmount);
    95
    96
        return (borrowedShares, borrowedAmount);
    97
      }
    98
    99
      /// @inheritdoc ISignatureGateway
    100
      function repayWithSig(
    101
        EIP712Types.Repay calldata params,
    102
        bytes calldata signature
    103
      ) external onlyRegisteredSpoke(params.spoke) returns (uint256, uint256) {
    104
        require(block.timestamp <= params.deadline, InvalidSignature());
    105
        address spoke = params.spoke;
    106
        uint256 reserveId = params.reserveId;
    107
        address user = params.onBehalfOf;
    108
        bytes32 digest = _hashTypedData(params.hash());
    109
        require(SignatureChecker.isValidSignatureNow(user, digest, signature), InvalidSignature());
    110
        _useCheckedNonce(user, params.nonce);
    111
    112
        IERC20 underlying = IERC20(_getReserveUnderlying(spoke, reserveId));
    113
        uint256 repayAmount = MathUtils.min(
    114
          params.amount,
    115
          ISpoke(spoke).getUserTotalDebt(reserveId, user)
    116
        );
    117
    118
        underlying.safeTransferFrom(user, address(this), repayAmount);
    119
        underlying.forceApprove(spoke, repayAmount);
    120
    121
        return ISpoke(spoke).repay(reserveId, repayAmount, user);
    122
      }
    123
    124
      /// @inheritdoc ISignatureGateway
    125
      function setUsingAsCollateralWithSig(
    126
        EIP712Types.SetUsingAsCollateral calldata params,
    127
        bytes calldata signature
    128
      ) external onlyRegisteredSpoke(params.spoke) {
    129
        require(block.timestamp <= params.deadline, InvalidSignature());
    130
        address user = params.onBehalfOf;
    131
        bytes32 digest = _hashTypedData(params.hash());
    132
        require(SignatureChecker.isValidSignatureNow(user, digest, signature), InvalidSignature());
    133
        _useCheckedNonce(user, params.nonce);
    134
    135
        ISpoke(params.spoke).setUsingAsCollateral(params.reserveId, params.useAsCollateral, user);
    136
      }
    137
    138
      /// @inheritdoc ISignatureGateway
    139
      function updateUserRiskPremiumWithSig(
    140
        EIP712Types.UpdateUserRiskPremium calldata params,
    141
        bytes calldata signature
    142
      ) external onlyRegisteredSpoke(params.spoke) {
    143
        require(block.timestamp <= params.deadline, InvalidSignature());
    144
        bytes32 digest = _hashTypedData(params.hash());
    145
        require(
    146
          SignatureChecker.isValidSignatureNow(params.user, digest, signature),
    147
          InvalidSignature()
    148
        );
    149
        _useCheckedNonce(params.user, params.nonce);
    150
    151
        ISpoke(params.spoke).updateUserRiskPremium(params.user);
    152
      }
    153
    154
      /// @inheritdoc ISignatureGateway
    155
      function updateUserDynamicConfigWithSig(
    156
        EIP712Types.UpdateUserDynamicConfig calldata params,
    157
        bytes calldata signature
    158
      ) external onlyRegisteredSpoke(params.spoke) {
    159
        require(block.timestamp <= params.deadline, InvalidSignature());
    160
        bytes32 digest = _hashTypedData(params.hash());
    161
        require(
    162
          SignatureChecker.isValidSignatureNow(params.user, digest, signature),
    163
          InvalidSignature()
    164
        );
    165
        _useCheckedNonce(params.user, params.nonce);
    166
    167
        ISpoke(params.spoke).updateUserDynamicConfig(params.user);
    168
      }
    169
    170
      /// @inheritdoc ISignatureGateway
    171
      function setSelfAsUserPositionManagerWithSig(
    172
        address spoke,
    173
        EIP712Types.SetUserPositionManager calldata params,
    174
        bytes calldata signature
    175
      ) external onlyRegisteredSpoke(spoke) {
    176
        try
    177
          ISpoke(spoke).setUserPositionManagerWithSig(
    178
            address(this),
    179
            params.user,
    180
            params.approve,
    181
            params.nonce,
    182
            params.deadline,
    183
            signature
    184
          )
    185
        {} catch {}
    186
      }
    187
    188
      /// @inheritdoc ISignatureGateway
    189
      function permitReserve(
    190
        address spoke,
    191
        uint256 reserveId,
    192
        address onBehalfOf,
    193
        uint256 value,
    194
        uint256 deadline,
    195
        uint8 permitV,
    196
        bytes32 permitR,
    197
        bytes32 permitS
    198
      ) external onlyRegisteredSpoke(spoke) {
    199
        address underlying = _getReserveUnderlying(spoke, reserveId);
    200
        try
    201
          IERC20Permit(underlying).permit({
    202
            owner: onBehalfOf,
    203
            spender: address(this),
    204
            value: value,
    205
            deadline: deadline,
    206
            v: permitV,
    207
            r: permitR,
    208
            s: permitS
    209
          })
    210
        {} catch {}
    211
      }
    212
    213
      /// @inheritdoc ISignatureGateway
    214
      function DOMAIN_SEPARATOR() external view returns (bytes32) {
    215
        return _domainSeparator();
    216
      }
    217
    218
      /// @inheritdoc ISignatureGateway
    219
      function SUPPLY_TYPEHASH() external pure returns (bytes32) {
    220
        return EIP712Hash.SUPPLY_TYPEHASH;
    221
      }
    222
    223
      /// @inheritdoc ISignatureGateway
    224
      function WITHDRAW_TYPEHASH() external pure returns (bytes32) {
    225
        return EIP712Hash.WITHDRAW_TYPEHASH;
    226
      }
    227
    228
      /// @inheritdoc ISignatureGateway
    229
      function BORROW_TYPEHASH() external pure returns (bytes32) {
    230
        return EIP712Hash.BORROW_TYPEHASH;
    231
      }
    232
    233
      /// @inheritdoc ISignatureGateway
    234
      function REPAY_TYPEHASH() external pure returns (bytes32) {
    235
        return EIP712Hash.REPAY_TYPEHASH;
    236
      }
    237
    238
      /// @inheritdoc ISignatureGateway
    239
      function SET_USING_AS_COLLATERAL_TYPEHASH() external pure returns (bytes32) {
    240
        return EIP712Hash.SET_USING_AS_COLLATERAL_TYPEHASH;
    241
      }
    242
    243
      /// @inheritdoc ISignatureGateway
    244
      function UPDATE_USER_RISK_PREMIUM_TYPEHASH() external pure returns (bytes32) {
    245
        return EIP712Hash.UPDATE_USER_RISK_PREMIUM_TYPEHASH;
    246
      }
    247
    248
      /// @inheritdoc ISignatureGateway
    249
      function UPDATE_USER_DYNAMIC_CONFIG_TYPEHASH() external pure returns (bytes32) {
    250
        return EIP712Hash.UPDATE_USER_DYNAMIC_CONFIG_TYPEHASH;
    251
      }
    252
    253
      function _domainNameAndVersion() internal pure override returns (string memory, string memory) {
    254
        return ('SignatureGateway', '1');
    255
      }
    256
    }
    257
    0.0% src/position-manager/interfaces/IGatewayBase.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    import {IRescuable} from 'src/interfaces/IRescuable.sol';
    6
    7
    /// @title IGatewayBase
    8
    /// @author Aave Labs
    9
    /// @notice Minimal interface for base gateway functionalities.
    10
    interface IGatewayBase is IRescuable {
    11
      /// @notice Emitted when a spoke is registered or deregistered.
    12
      event SpokeRegistered(address indexed spoke, bool active);
    13
    14
      /// @notice Thrown when the specified address is invalid.
    15
      error InvalidAddress();
    16
    17
      /// @notice Thrown when the specified amount is invalid.
    18
      error InvalidAmount();
    19
    20
      /// @notice Thrown when the specified spoke is not registered.
    21
      error SpokeNotRegistered();
    22
    23
      /// @notice Allows contract to renounce its position manager role for `user`.
    24
      /// @dev Only authorized caller to invoke this method.
    25
      /// @param spoke The address of the registered `spoke`.
    26
      /// @param user The address of the user to renounce the position manager role for.
    27
      function renouncePositionManagerRole(address spoke, address user) external;
    28
    29
      /// @notice Permissioned operation to register or deregister a spoke.
    30
      /// @dev Only owner to invoke this method.
    31
      /// @param spoke The address of the `spoke`.
    32
      /// @param active `true` to register, `false` to deregister.
    33
      function registerSpoke(address spoke, bool active) external;
    34
    35
      /// @notice Returns whether the specified spoke is registered.
    36
      /// @param spoke The address of the `spoke`.
    37
      /// @return `true` if the spoke is registered, `false` otherwise.
    38
      function isSpokeRegistered(address spoke) external view returns (bool);
    39
    }
    40
    0.0% src/position-manager/interfaces/INativeTokenGateway.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    import {IGatewayBase} from 'src/position-manager/interfaces/IGatewayBase.sol';
    6
    7
    /// @title INativeTokenGateway
    8
    /// @author Aave Labs
    9
    /// @notice Abstracts actions to the protocol involving the native token.
    10
    /// @dev Must be set as `PositionManager` on the spoke for the user.
    11
    interface INativeTokenGateway is IGatewayBase {
    12
      /// @notice Thrown when the underlying asset is not the wrapped native asset.
    13
      error NotNativeWrappedAsset();
    14
    15
      /// @notice Thrown when the native amount sent does not match the given amount parameter.
    16
      error NativeAmountMismatch();
    17
    18
      /// @notice Thrown when trying to call an unsupported action or sending native assets to this contract directly.
    19
      error UnsupportedAction();
    20
    21
      /// @notice Wraps the native asset and supplies to a specified registered `spoke`.
    22
      /// @dev Contract must be an active & approved user position manager of the caller.
    23
      /// @param spoke The address of the registered `spoke`.
    24
      /// @param reserveId The identifier of the reserve for the wrapped asset.
    25
      /// @param amount Amount to wrap and supply.
    26
      /// @return The amount of shares supplied.
    27
      /// @return The amount of assets supplied.
    28
      function supplyNative(
    29
        address spoke,
    30
        uint256 reserveId,
    31
        uint256 amount
    32
      ) external payable returns (uint256, uint256);
    33
    34
      /// @notice Wraps the native asset,supplies to a specified registered `spoke` and sets it as collateral.
    35
      /// @dev Contract must be an active & approved user position manager of the caller.
    36
      /// @param spoke The address of the registered `spoke`.
    37
      /// @param reserveId The identifier of the reserve for the wrapped asset.
    38
      /// @param amount Amount to wrap and supply.
    39
      /// @return The amount of shares supplied.
    40
      /// @return The amount of assets supplied.
    41
      function supplyAsCollateralNative(
    42
        address spoke,
    43
        uint256 reserveId,
    44
        uint256 amount
    45
      ) external payable returns (uint256, uint256);
    46
    47
      /// @notice Withdraws the wrapped asset from a specified registered `spoke` and unwraps it back to the native asset.
    48
      /// @dev Contract must be an active & approved user position manager of the caller.
    49
      /// @param spoke The address of the registered `spoke`.
    50
      /// @param reserveId The identifier of the reserve for the wrapped asset.
    51
      /// @param amount Amount to withdraw and unwrap.
    52
      /// @return The amount of shares withdrawn.
    53
      /// @return The amount of assets withdrawn.
    54
      function withdrawNative(
    55
        address spoke,
    56
        uint256 reserveId,
    57
        uint256 amount
    58
      ) external returns (uint256, uint256);
    59
    60
      /// @notice Borrows the wrapped asset from a specified registered `spoke` and unwraps it back to the native asset.
    61
      /// @dev Contract must be an active & approved user position manager of the caller.
    62
      /// @param spoke The address of the registered `spoke`.
    63
      /// @param reserveId The identifier of the reserve for the wrapped asset.
    64
      /// @param amount Amount to borrow and unwrap.
    65
      /// @return The amount of shares borrowed.
    66
      /// @return The amount of assets borrowed.
    67
      function borrowNative(
    68
        address spoke,
    69
        uint256 reserveId,
    70
        uint256 amount
    71
      ) external returns (uint256, uint256);
    72
    73
      /// @notice Wraps the native asset and repays debt on a specified registered `spoke`.
    74
      /// @dev It refunds any excess funds sent beyond the required debt repayment.
    75
      /// @dev Contract must be an active & approved user position manager of the caller.
    76
      /// @param spoke The address of the registered `spoke`.
    77
      /// @param reserveId The identifier of the reserve for the wrapped asset.
    78
      /// @param amount Amount to wrap and repay.
    79
      /// @return The amount of shares repaid.
    80
      /// @return The amount of assets repaid.
    81
      function repayNative(
    82
        address spoke,
    83
        uint256 reserveId,
    84
        uint256 amount
    85
      ) external payable returns (uint256, uint256);
    86
    87
      /// @notice Returns the address of Native Wrapper.
    88
      function NATIVE_WRAPPER() external view returns (address);
    89
    }
    90
    0.0% src/position-manager/interfaces/INativeWrapper.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    import {IERC20} from 'src/dependencies/openzeppelin/IERC20.sol';
    6
    7
    /// @title INativeWrapper interface
    8
    /// @author Aave Labs
    9
    /// @notice Minimal interface for interacting with a wrapped native token contract.
    10
    interface INativeWrapper is IERC20 {
    11
      /// @notice Deposit native currency and receive wrapped tokens.
    12
      function deposit() external payable;
    13
    14
      /// @notice Withdraw native currency by burning wrapped tokens.
    15
      /// @param amount The amount of wrapped tokens to burn for native currency.
    16
      function withdraw(uint256 amount) external;
    17
    }
    18
    0.0% src/position-manager/interfaces/ISignatureGateway.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    import {IMulticall} from 'src/interfaces/IMulticall.sol';
    6
    import {INoncesKeyed} from 'src/interfaces/INoncesKeyed.sol';
    7
    import {EIP712Types} from 'src/libraries/types/EIP712Types.sol';
    8
    import {IGatewayBase} from 'src/position-manager/interfaces/IGatewayBase.sol';
    9
    10
    /// @title ISignatureGateway
    11
    /// @author Aave Labs
    12
    /// @notice Minimal interface for protocol actions involving signed intents.
    13
    interface ISignatureGateway is IMulticall, INoncesKeyed, IGatewayBase {
    14
      /// @notice Thrown when signature deadline has passed or signer is not `onBehalfOf`.
    15
      error InvalidSignature();
    16
    17
      /// @notice Facilitates `supply` action on the specified registered `spoke` with a typed signature from `onBehalfOf`.
    18
      /// @dev Supplied assets are pulled from `onBehalfOf`, prior approval to this gateway is required.
    19
      /// @dev Uses keyed-nonces where for each key's namespace nonce is consumed sequentially.
    20
      /// @param params The structured supply parameters.
    21
      /// @param signature The signed bytes for the intent.
    22
      /// @return The amount of shares supplied.
    23
      /// @return The amount of assets supplied.
    24
      function supplyWithSig(
    25
        EIP712Types.Supply calldata params,
    26
        bytes calldata signature
    27
      ) external returns (uint256, uint256);
    28
    29
      /// @notice Facilitates `withdraw` action on the specified registered `spoke` with a typed signature from `onBehalfOf`.
    30
      /// @dev Providing an amount exceeding the user's current withdrawable balance indicates a request for a maximum withdrawal.
    31
      /// @dev Withdrawn assets are pushed to `onBehalfOf`.
    32
      /// @dev Uses keyed-nonces where for each key's namespace nonce is consumed sequentially.
    33
      /// @param params The structured withdraw parameters.
    34
      /// @param signature The signed bytes for the intent.
    35
      /// @return The amount of shares withdrawn.
    36
      /// @return The amount of assets withdrawn.
    37
      function withdrawWithSig(
    38
        EIP712Types.Withdraw calldata params,
    39
        bytes calldata signature
    40
      ) external returns (uint256, uint256);
    41
    42
      /// @notice Facilitates `borrow` action on the specified registered `spoke` with a typed signature from `onBehalfOf`.
    43
      /// @dev Borrowed assets are pushed to `onBehalfOf`.
    44
      /// @dev Uses keyed-nonces where for each key's namespace nonce is consumed sequentially.
    45
      /// @param params The structured borrow parameters.
    46
      /// @param signature The signed bytes for the intent.
    47
      /// @return The amount of shares borrowed.
    48
      /// @return The amount of assets borrowed.
    49
      function borrowWithSig(
    50
        EIP712Types.Borrow calldata params,
    51
        bytes calldata signature
    52
      ) external returns (uint256, uint256);
    53
    54
      /// @notice Facilitates `repay` action on the specified registered `spoke` with a typed signature from `onBehalfOf`.
    55
      /// @dev Repay assets are pulled from `onBehalfOf`, prior approval to this gateway is required.
    56
      /// @dev Providing an amount greater than the user's current debt indicates a request to repay the maximum possible amount.
    57
      /// @dev Uses keyed-nonces where for each key's namespace nonce is consumed sequentially.
    58
      /// @param params The structured repay parameters.
    59
      /// @param signature The signed bytes for the intent.
    60
      /// @return The amount of shares repaid.
    61
      /// @return The amount of assets repaid.
    62
      function repayWithSig(
    63
        EIP712Types.Repay calldata params,
    64
        bytes calldata signature
    65
      ) external returns (uint256, uint256);
    66
    67
      /// @notice Facilitates `setUsingAsCollateral` action on the specified registered `spoke` with a typed signature from `onBehalfOf`.
    68
      /// @dev Uses keyed-nonces where for each key's namespace nonce is consumed sequentially.
    69
      /// @param params The structured setUsingAsCollateral parameters.
    70
      /// @param signature The signed bytes for the intent.
    71
      function setUsingAsCollateralWithSig(
    72
        EIP712Types.SetUsingAsCollateral calldata params,
    73
        bytes calldata signature
    74
      ) external;
    75
    76
      /// @notice Facilitates `updateUserRiskPremium` action on the specified registered `spoke` with a typed signature from `user`.
    77
      /// @dev Uses keyed-nonces where for each key's namespace nonce is consumed sequentially.
    78
      /// @param params The structured updateUserRiskPremium parameters.
    79
      /// @param signature The signed bytes for the intent.
    80
      function updateUserRiskPremiumWithSig(
    81
        EIP712Types.UpdateUserRiskPremium calldata params,
    82
        bytes calldata signature
    83
      ) external;
    84
    85
      /// @notice Facilitates `updateUserDynamicConfig` action on the specified registered `spoke` with a typed signature from `user`.
    86
      /// @dev Uses keyed-nonces where for each key's namespace nonce is consumed sequentially.
    87
      /// @param params The structured updateUserDynamicConfig parameters.
    88
      /// @param signature The signed bytes for the intent.
    89
      function updateUserDynamicConfigWithSig(
    90
        EIP712Types.UpdateUserDynamicConfig calldata params,
    91
        bytes calldata signature
    92
      ) external;
    93
    94
      /// @notice Facilitates setting this gateway as user position manager on the specified registered `spoke`
    95
      /// with a typed signature from `user`.
    96
      /// @dev The signature is consumed on the the specified registered `spoke`.
    97
      /// @dev The given data is passed to the `spoke` for the signature to be verified.
    98
      /// @param spoke The address of the spoke.
    99
      /// @param params The structured setSelfAsUserPositionManager parameters.
    100
      /// @param signature The signed bytes for the intent.
    101
      function setSelfAsUserPositionManagerWithSig(
    102
        address spoke,
    103
        EIP712Types.SetUserPositionManager calldata params,
    104
        bytes calldata signature
    105
      ) external;
    106
    107
      /// @notice Facilitates consuming a permit for the given reserve's underlying asset on the specified registered `spoke`.
    108
      /// @dev The given data is passed to the underlying asset for the signature to be verified.
    109
      /// @dev Spender is this gateway contract.
    110
      /// @param spoke The address of the spoke.
    111
      /// @param reserveId The identifier of the reserve.
    112
      /// @param onBehalfOf The address of the user on whose behalf the permit is being used.
    113
      /// @param value The amount of the underlying asset to permit.
    114
      /// @param deadline The deadline for the permit.
    115
      function permitReserve(
    116
        address spoke,
    117
        uint256 reserveId,
    118
        address onBehalfOf,
    119
        uint256 value,
    120
        uint256 deadline,
    121
        uint8 permitV,
    122
        bytes32 permitR,
    123
        bytes32 permitS
    124
      ) external;
    125
    126
      /// @notice Returns the EIP712 domain separator.
    127
      function DOMAIN_SEPARATOR() external view returns (bytes32);
    128
    129
      /// @notice Returns the type hash for the Supply intent.
    130
      function SUPPLY_TYPEHASH() external view returns (bytes32);
    131
    132
      /// @notice Returns the type hash for the Withdraw intent.
    133
      function WITHDRAW_TYPEHASH() external view returns (bytes32);
    134
    135
      /// @notice Returns the type hash for the Borrow intent.
    136
      function BORROW_TYPEHASH() external view returns (bytes32);
    137
    138
      /// @notice Returns the type hash for the Repay intent.
    139
      function REPAY_TYPEHASH() external view returns (bytes32);
    140
    141
      /// @notice Returns the type hash for the SetUsingAsCollateral intent.
    142
      function SET_USING_AS_COLLATERAL_TYPEHASH() external view returns (bytes32);
    143
    144
      /// @notice Returns the type hash for the UpdateUserRiskPremium intent.
    145
      function UPDATE_USER_RISK_PREMIUM_TYPEHASH() external view returns (bytes32);
    146
    147
      /// @notice Returns the type hash for the UpdateUserDynamicConfig intent.
    148
      function UPDATE_USER_DYNAMIC_CONFIG_TYPEHASH() external view returns (bytes32);
    149
    }
    150
    4.0% src/position-manager/libraries/EIP712Hash.sol
    Lines covered: 2 / 48 (4.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.20;
    4
    5
    import {EIP712Types} from 'src/libraries/types/EIP712Types.sol';
    6
    7
    /// @title EIP712Hash library
    8
    /// @author Aave Labs
    9
    /// @notice Helper methods to hash EIP712 typed data structs.
    10
    library EIP712Hash {
    11
      bytes32 public constant SUPPLY_TYPEHASH =
    12
        // keccak256('Supply(address spoke,uint256 reserveId,uint256 amount,address onBehalfOf,uint256 nonce,uint256 deadline)')
    13
        0xe85497eb293c001e8483fe105efadd1d50aa0dadfc0570b27058031dfceab2e6;
    14
    15
      bytes32 public constant WITHDRAW_TYPEHASH =
    16
        // keccak256('Withdraw(address spoke,uint256 reserveId,uint256 amount,address onBehalfOf,uint256 nonce,uint256 deadline)')
    17
        0x0bc73eb58cf4068a29b9593ef18c0d26b3b4453bd2155424a90cb26a22f41d7f;
    18
    19
      bytes32 public constant BORROW_TYPEHASH =
    20
        // keccak256('Borrow(address spoke,uint256 reserveId,uint256 amount,address onBehalfOf,uint256 nonce,uint256 deadline)')
    21
        0xe248895a233688ba2a70b6f560472dbc27e35ece0d86914f7d43bf2f7df8025b;
    22
    23
      bytes32 public constant REPAY_TYPEHASH =
    24
        // keccak256('Repay(address spoke,uint256 reserveId,uint256 amount,address onBehalfOf,uint256 nonce,uint256 deadline)')
    25
        0xd23fe99a7aac398d03952a098faa8889259d062784bd80ea0f159e4af604c045;
    26
    27
      bytes32 public constant SET_USING_AS_COLLATERAL_TYPEHASH =
    28
        // keccak256('SetUsingAsCollateral(address spoke,uint256 reserveId,bool useAsCollateral,address onBehalfOf,uint256 nonce,uint256 deadline)')
    29
        0xd4350e1f25ecd62a35b50e8cd1e00bc34331ae8c728ee4dbb69ecf1023daecf7;
    30
    31
      bytes32 public constant UPDATE_USER_RISK_PREMIUM_TYPEHASH =
    32
        // keccak256('UpdateUserRiskPremium(address spoke,address user,uint256 nonce,uint256 deadline)')
    33
        0xb41e132023782c9b02febf1b9b7fe98c4a73f57ebc63ba44cd71f6365ea09eaf;
    34
    35
      bytes32 public constant UPDATE_USER_DYNAMIC_CONFIG_TYPEHASH =
    36
        // keccak256('UpdateUserDynamicConfig(address spoke,address user,uint256 nonce,uint256 deadline)')
    37
        0xba177b1f5b5e1e709f62c19f03c97988c57752ba561de58f383ebee4e8d0a71c;
    38
    39
      function hash(EIP712Types.Supply calldata params) internal pure returns (bytes32) {
    40
        return
    41
          keccak256(
    42
            abi.encode(
    43
              SUPPLY_TYPEHASH,
    44
              params.spoke,
    45
              params.reserveId,
    46
              params.amount,
    47
              params.onBehalfOf,
    48
              params.nonce,
    49
              params.deadline
    50
            )
    51
          );
    52
      }
    53
    54
      function hash(EIP712Types.Withdraw calldata params) internal pure returns (bytes32) {
    55
        return
    56
          keccak256(
    57
            abi.encode(
    58
              WITHDRAW_TYPEHASH,
    59
              params.spoke,
    60
              params.reserveId,
    61
              params.amount,
    62
              params.onBehalfOf,
    63
              params.nonce,
    64
              params.deadline
    65
            )
    66
          );
    67
      }
    68
    69
      function hash(EIP712Types.Borrow calldata params) internal pure returns (bytes32) {
    70
        return
    71
          keccak256(
    72
            abi.encode(
    73
              BORROW_TYPEHASH,
    74
              params.spoke,
    75
              params.reserveId,
    76
              params.amount,
    77
              params.onBehalfOf,
    78
              params.nonce,
    79
              params.deadline
    80
            )
    81
          );
    82
      }
    83
    84
      function hash(EIP712Types.Repay calldata params) internal pure returns (bytes32) {
    85
        return
    86
          keccak256(
    87
            abi.encode(
    88
              REPAY_TYPEHASH,
    89
              params.spoke,
    90
              params.reserveId,
    91
              params.amount,
    92
              params.onBehalfOf,
    93
              params.nonce,
    94
              params.deadline
    95
            )
    96
          );
    97
      }
    98
    99
      function hash(EIP712Types.SetUsingAsCollateral calldata params) internal pure returns (bytes32) {
    100
        return
    101
          keccak256(
    102
            abi.encode(
    103
              SET_USING_AS_COLLATERAL_TYPEHASH,
    104
              params.spoke,
    105
              params.reserveId,
    106
              params.useAsCollateral,
    107
              params.onBehalfOf,
    108
              params.nonce,
    109
              params.deadline
    110
            )
    111
          );
    112
      }
    113
    114
      function hash(EIP712Types.UpdateUserRiskPremium calldata params) internal pure returns (bytes32) {
    115
        return
    116
          keccak256(
    117
            abi.encode(
    118
              UPDATE_USER_RISK_PREMIUM_TYPEHASH,
    119
              params.spoke,
    120
              params.user,
    121
              params.nonce,
    122
              params.deadline
    123
            )
    124
          );
    125
      }
    126
    127
      function hash(
    128
        EIP712Types.UpdateUserDynamicConfig calldata params
    129
      ) internal pure returns (bytes32) {
    130
        return
    131
          keccak256(
    132
            abi.encode(
    133
              UPDATE_USER_DYNAMIC_CONFIG_TYPEHASH,
    134
              params.spoke,
    135
              params.user,
    136
              params.nonce,
    137
              params.deadline
    138
            )
    139
          );
    140
      }
    141
    }
    142
    90.0% src/spoke/AaveOracle.sol
    Lines covered: 30 / 33 (90.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity 0.8.28;
    4
    5
    import {AggregatorV3Interface} from 'src/dependencies/chainlink/AggregatorV3Interface.sol';
    6
    import {IAaveOracle, IPriceOracle} from 'src/spoke/interfaces/IAaveOracle.sol';
    7
    8
    /// @title AaveOracle
    9
    /// @author Aave Labs
    10
    /// @notice Provides reserve prices.
    11
    /// @dev Oracles are spoke-specific, due to the usage of reserve id as index of the `_sources` mapping.
    12
    contract AaveOracle is IAaveOracle {
    13
      /// @inheritdoc IPriceOracle
    14
      address public SPOKE;
    15
    16
      /// @inheritdoc IPriceOracle
    17
      uint8 public immutable DECIMALS;
    18
    19
      /// @inheritdoc IAaveOracle
    20
      string public DESCRIPTION;
    21
    22
      mapping(uint256 reserveId => AggregatorV3Interface) internal _sources;
    23
    24
      /// @dev Constructor.
    25
      /// @dev `decimals` must match the spoke's decimals for compatibility.
    26
      /// @param spoke_ The address of the spoke contract.
    27
      /// @param decimals_ The number of decimals for the oracle.
    28
      /// @param description_ The description of the oracle.
    29
      constructor(address spoke_, uint8 decimals_, string memory description_) {
    30
        require(spoke_ != address(0), InvalidAddress());
    31
        SPOKE = spoke_;
    32
        DECIMALS = decimals_;
    33
        DESCRIPTION = description_;
    34
      }
    35
    36
      // @audit FIXME: This is a hack to set the spoke after the oracle is deployed so that it does not rely on vm.computeCreateAddress.
    37
      function setSpoke(address spoke) external {
    38
        SPOKE = spoke;
    39
      }
    40
    41
      /// @inheritdoc IAaveOracle
    42
      function setReserveSource(uint256 reserveId, address source) external {
    43
        require(msg.sender == SPOKE, OnlySpoke());
    44
        AggregatorV3Interface targetSource = AggregatorV3Interface(source);
    45
        require(targetSource.decimals() == DECIMALS, InvalidSourceDecimals(reserveId));
    46
        _sources[reserveId] = targetSource;
    47
        _getSourcePrice(reserveId);
    48
        emit UpdateReserveSource(reserveId, source);
    49
      }
    50
    51
      /// @inheritdoc IPriceOracle
    52
      function getReservePrice(uint256 reserveId) external view returns (uint256) {
    53
        return _getSourcePrice(reserveId);
    54
      }
    55
    56
      /// @inheritdoc IAaveOracle
    57
      function getReservesPrices(
    58
        uint256[] calldata reserveIds
    59
      ) external view returns (uint256[] memory) {
    60
        uint256[] memory prices = new uint256[](reserveIds.length);
    61
        for (uint256 i = 0; i < reserveIds.length; ++i) {
    62
          prices[i] = _getSourcePrice(reserveIds[i]);
    63
        }
    64
        return prices;
    65
      }
    66
    67
      /// @inheritdoc IAaveOracle
    68
      function getReserveSource(uint256 reserveId) external view returns (address) {
    69
        return address(_sources[reserveId]);
    70
      }
    71
    72
      /// @dev Price of zero will revert with `InvalidPrice`.
    73
      function _getSourcePrice(uint256 reserveId) internal view returns (uint256) {
    74
        AggregatorV3Interface source = _sources[reserveId];
    75
        require(address(source) != address(0), InvalidSource(reserveId));
    76
    77
        (, int256 price, , , ) = source.latestRoundData();
    78
        require(price > 0, InvalidPrice(reserveId));
    79
    80
        return uint256(price);
    81
      }
    82
    }
    83
    73.0% src/spoke/Spoke.sol
    Lines covered: 337 / 461 (73.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity 0.8.28;
    4
    5
    import {SafeCast} from 'src/dependencies/openzeppelin/SafeCast.sol';
    6
    import {SafeERC20, IERC20} from 'src/dependencies/openzeppelin/SafeERC20.sol';
    7
    import {IERC20Permit} from 'src/dependencies/openzeppelin/IERC20Permit.sol';
    8
    import {SignatureChecker} from 'src/dependencies/openzeppelin/SignatureChecker.sol';
    9
    import {AccessManagedUpgradeable} from 'src/dependencies/openzeppelin-upgradeable/AccessManagedUpgradeable.sol';
    10
    import {EIP712} from 'src/dependencies/solady/EIP712.sol';
    11
    import {MathUtils} from 'src/libraries/math/MathUtils.sol';
    12
    import {PercentageMath} from 'src/libraries/math/PercentageMath.sol';
    13
    import {WadRayMath} from 'src/libraries/math/WadRayMath.sol';
    14
    import {KeyValueList} from 'src/spoke/libraries/KeyValueList.sol';
    15
    import {LiquidationLogic} from 'src/spoke/libraries/LiquidationLogic.sol';
    16
    import {PositionStatusMap} from 'src/spoke/libraries/PositionStatusMap.sol';
    17
    import {ReserveFlags, ReserveFlagsMap} from 'src/spoke/libraries/ReserveFlagsMap.sol';
    18
    import {UserPositionDebt} from 'src/spoke/libraries/UserPositionDebt.sol';
    19
    import {NoncesKeyed} from 'src/utils/NoncesKeyed.sol';
    20
    import {Multicall} from 'src/utils/Multicall.sol';
    21
    import {IAaveOracle} from 'src/spoke/interfaces/IAaveOracle.sol';
    22
    import {IHubBase} from 'src/hub/interfaces/IHubBase.sol';
    23
    import {ISpokeBase, ISpoke} from 'src/spoke/interfaces/ISpoke.sol';
    24
    25
    /// @title Spoke
    26
    /// @author Aave Labs
    27
    /// @notice Handles risk configuration & borrowing strategy for reserves and user positions.
    28
    /// @dev Each reserve can be associated with a separate Hub.
    29
    abstract contract Spoke is ISpoke, Multicall, NoncesKeyed, AccessManagedUpgradeable, EIP712 {
    30
      using SafeCast for *;
    31
      using SafeERC20 for IERC20;
    32
      using MathUtils for *;
    33
      using PercentageMath for *;
    34
      using WadRayMath for *;
    35
      using KeyValueList for KeyValueList.List;
    36
      using LiquidationLogic for *;
    37
      using PositionStatusMap for *;
    38
      using ReserveFlagsMap for ReserveFlags;
    39
      using UserPositionDebt for ISpoke.UserPosition;
    40
    41
      /// @inheritdoc ISpoke
    42
      bytes32 public constant SET_USER_POSITION_MANAGER_TYPEHASH =
    43
        // keccak256('SetUserPositionManager(address positionManager,address user,bool approve,uint256 nonce,uint256 deadline)')
    44
        0x758d23a3c07218b7ea0b4f7f63903c4e9d5cbde72d3bcfe3e9896639025a0214;
    45
    46
      /// @inheritdoc ISpoke
    47
      address public immutable ORACLE;
    48
    49
      /// @dev The maximum allowed value for an asset identifier (inclusive).
    50
      uint256 internal constant MAX_ALLOWED_ASSET_ID = type(uint16).max;
    51
    52
      /// @dev The maximum allowed collateral risk value for a reserve, expressed in BPS (e.g. 100_00 is 100.00%).
    53
      uint24 internal constant MAX_ALLOWED_COLLATERAL_RISK = 1000_00;
    54
    55
      /// @dev The maximum allowed value for a dynamic configuration key (inclusive).
    56
      uint256 internal constant MAX_ALLOWED_DYNAMIC_CONFIG_KEY = type(uint24).max;
    57
    58
      /// @dev The minimum health factor below which a position is considered unhealthy and subject to liquidation.
    59
      /// @dev Expressed in WAD (18 decimals) (e.g. 1e18 is 1.00).
    60
      uint64 internal constant HEALTH_FACTOR_LIQUIDATION_THRESHOLD =
    61
        LiquidationLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD;
    62
    63
      /// @dev The maximum amount considered as dust for a user's collateral and debt balances after a liquidation.
    64
      /// @dev Expressed in USD with 26 decimals.
    65
      uint256 internal constant DUST_LIQUIDATION_THRESHOLD =
    66
        LiquidationLogic.DUST_LIQUIDATION_THRESHOLD;
    67
    68
      /// @dev The number of decimals used by the oracle.
    69
      uint8 internal constant ORACLE_DECIMALS = 8;
    70
    71
      /// @dev Number of reserves listed in the Spoke.
    72
      uint256 internal _reserveCount;
    73
    74
      /// @dev Map of user addresses and reserve identifiers to user positions.
    75
      mapping(address user => mapping(uint256 reserveId => UserPosition)) internal _userPositions;
    76
    77
      /// @dev Map of user addresses to their position status.
    78
      mapping(address user => PositionStatus) internal _positionStatus;
    79
    80
      /// @dev Map of reserve identifiers to their Reserve data.
    81
      mapping(uint256 reserveId => Reserve) internal _reserves;
    82
    83
      /// @dev Map of position manager addresses to their configuration data.
    84
      mapping(address positionManager => PositionManagerConfig) internal _positionManager;
    85
    86
      /// @dev Map of reserve identifiers and dynamic configuration keys to the dynamic configuration data.
    87
      mapping(uint256 reserveId => mapping(uint24 dynamicConfigKey => DynamicReserveConfig))
    88
        internal _dynamicConfig;
    89
    90
      /// @dev Liquidation configuration for the Spoke.
    91
      LiquidationConfig internal _liquidationConfig;
    92
    93
      /// @dev Map of hub addresses and asset identifiers to whether the reserve exists.
    94
      mapping(address hub => mapping(uint256 assetId => bool)) internal _reserveExists;
    95
    96
      /// @notice Modifier that checks if the caller is an approved positionManager for `onBehalfOf`.
    97
      modifier onlyPositionManager(address onBehalfOf) {
    98
        require(_isPositionManager({user: onBehalfOf, manager: msg.sender}), Unauthorized());
    99
        _;
    100
      }
    101
    102
      /// @dev Constructor.
    103
      /// @param oracle_ The address of the AaveOracle contract.
    104
      constructor(address oracle_) {
    105
        require(IAaveOracle(oracle_).DECIMALS() == ORACLE_DECIMALS, InvalidOracleDecimals());
    106
        ORACLE = oracle_;
    107
      }
    108
    109
      /// @dev To be overridden by the inheriting Spoke instance contract.
    110
      function initialize(address authority) external virtual;
    111
    112
      /// @inheritdoc ISpoke
    113
      function updateLiquidationConfig(LiquidationConfig calldata config) external restricted {
    114
        require(
    115
          config.targetHealthFactor >= HEALTH_FACTOR_LIQUIDATION_THRESHOLD &&
    116
            config.liquidationBonusFactor <= PercentageMath.PERCENTAGE_FACTOR &&
    117
            config.healthFactorForMaxBonus < HEALTH_FACTOR_LIQUIDATION_THRESHOLD,
    118
          InvalidLiquidationConfig()
    119
        );
    120
        _liquidationConfig = config;
    121
        emit UpdateLiquidationConfig(config);
    122
      }
    123
    124
      /// @inheritdoc ISpoke
    125
      function addReserve(
    126
        address hub,
    127
        uint256 assetId,
    128
        address priceSource,
    129
        ReserveConfig calldata config,
    130
        DynamicReserveConfig calldata dynamicConfig
    131
      ) external restricted returns (uint256) {
    132
        require(hub != address(0), InvalidAddress());
    133
        require(assetId <= MAX_ALLOWED_ASSET_ID, InvalidAssetId());
    134
        require(!_reserveExists[hub][assetId], ReserveExists());
    135
    136
        _validateReserveConfig(config);
    137
        _validateDynamicReserveConfig(dynamicConfig);
    138
        uint256 reserveId = _reserveCount++;
    139
        uint24 dynamicConfigKey; // 0 as first key to use
    140
    141
        (address underlying, uint8 decimals) = IHubBase(hub).getAssetUnderlyingAndDecimals(assetId);
    142
        require(underlying != address(0), AssetNotListed());
    143
    144
        _updateReservePriceSource(reserveId, priceSource);
    145
    146
        _reserves[reserveId] = Reserve({
    147
          underlying: underlying,
    148
          hub: IHubBase(hub),
    149
          assetId: assetId.toUint16(),
    150
          decimals: decimals,
    151
          dynamicConfigKey: dynamicConfigKey,
    152
          collateralRisk: config.collateralRisk,
    153
          flags: ReserveFlagsMap.create({
    154
            initPaused: config.paused,
    155
            initFrozen: config.frozen,
    156
            initBorrowable: config.borrowable,
    157
            initLiquidatable: config.liquidatable,
    158
            initReceiveSharesEnabled: config.receiveSharesEnabled
    159
          })
    160
        });
    161
        _dynamicConfig[reserveId][dynamicConfigKey] = dynamicConfig;
    162
        _reserveExists[hub][assetId] = true;
    163
    164
        emit AddReserve(reserveId, assetId, hub);
    165
        emit UpdateReserveConfig(reserveId, config);
    166
        emit AddDynamicReserveConfig(reserveId, dynamicConfigKey, dynamicConfig);
    167
    168
        return reserveId;
    169
      }
    170
    171
      /// @inheritdoc ISpoke
    172
      function updateReserveConfig(
    173
        uint256 reserveId,
    174
        ReserveConfig calldata config
    175
      ) external restricted {
    176
        Reserve storage reserve = _getReserve(reserveId);
    177
        _validateReserveConfig(config);
    178
        reserve.collateralRisk = config.collateralRisk;
    179
        reserve.flags = ReserveFlagsMap.create({
    180
          initPaused: config.paused,
    181
          initFrozen: config.frozen,
    182
          initBorrowable: config.borrowable,
    183
          initLiquidatable: config.liquidatable,
    184
          initReceiveSharesEnabled: config.receiveSharesEnabled
    185
        });
    186
        emit UpdateReserveConfig(reserveId, config);
    187
      }
    188
    189
      /// @inheritdoc ISpoke
    190
      function updateReservePriceSource(uint256 reserveId, address priceSource) external restricted {
    191
        require(reserveId < _reserveCount, ReserveNotListed());
    192
        _updateReservePriceSource(reserveId, priceSource);
    193
      }
    194
    195
      /// @inheritdoc ISpoke
    196
      function addDynamicReserveConfig(
    197
        uint256 reserveId,
    198
        DynamicReserveConfig calldata dynamicConfig
    199
      ) external restricted returns (uint24) {
    200
        require(reserveId < _reserveCount, ReserveNotListed());
    201
        uint24 dynamicConfigKey = _reserves[reserveId].dynamicConfigKey;
    202
        require(dynamicConfigKey < MAX_ALLOWED_DYNAMIC_CONFIG_KEY, MaximumDynamicConfigKeyReached());
    203
        _validateDynamicReserveConfig(dynamicConfig);
    204
        dynamicConfigKey = dynamicConfigKey.uncheckedAdd(1).toUint24();
    205
        _reserves[reserveId].dynamicConfigKey = dynamicConfigKey;
    206
        _dynamicConfig[reserveId][dynamicConfigKey] = dynamicConfig;
    207
        emit AddDynamicReserveConfig(reserveId, dynamicConfigKey, dynamicConfig);
    208
        return dynamicConfigKey;
    209
      }
    210
    211
      /// @inheritdoc ISpoke
    212
      function updateDynamicReserveConfig(
    213
        uint256 reserveId,
    214
        uint24 dynamicConfigKey,
    215
        DynamicReserveConfig calldata dynamicConfig
    216
      ) external restricted {
    217
        require(reserveId < _reserveCount, ReserveNotListed());
    218
        _validateUpdateDynamicReserveConfig(_dynamicConfig[reserveId][dynamicConfigKey], dynamicConfig);
    219
        _dynamicConfig[reserveId][dynamicConfigKey] = dynamicConfig;
    220
        emit UpdateDynamicReserveConfig(reserveId, dynamicConfigKey, dynamicConfig);
    221
      }
    222
    223
      /// @inheritdoc ISpoke
    224
      function updatePositionManager(address positionManager, bool active) external restricted {
    225
        _positionManager[positionManager].active = active;
    226
        emit UpdatePositionManager(positionManager, active);
    227
      }
    228
    229
      /// @inheritdoc ISpokeBase
    230
      function supply(
    231
        uint256 reserveId,
    232
        uint256 amount,
    233
        address onBehalfOf
    234
      ) external onlyPositionManager(onBehalfOf) returns (uint256, uint256) {
    235
        Reserve storage reserve = _getReserve(reserveId);
    236
        UserPosition storage userPosition = _userPositions[onBehalfOf][reserveId];
    237
        _validateSupply(reserve.flags);
    238
    239
        IERC20(reserve.underlying).safeTransferFrom(msg.sender, address(reserve.hub), amount);
    240
        uint256 suppliedShares = reserve.hub.add(reserve.assetId, amount);
    241
        userPosition.suppliedShares += suppliedShares.toUint120();
    242
    243
        emit Supply(reserveId, msg.sender, onBehalfOf, suppliedShares, amount);
    244
    245
        return (suppliedShares, amount);
    246
      }
    247
    248
      /// @inheritdoc ISpokeBase
    249
      function withdraw(
    250
        uint256 reserveId,
    251
        uint256 amount,
    252
        address onBehalfOf
    253
      ) external onlyPositionManager(onBehalfOf) returns (uint256, uint256) {
    254
        Reserve storage reserve = _getReserve(reserveId);
    255
        UserPosition storage userPosition = _userPositions[onBehalfOf][reserveId];
    256
        _validateWithdraw(reserve.flags);
    257
        IHubBase hub = reserve.hub;
    258
        uint256 assetId = reserve.assetId;
    259
    260
        uint256 withdrawnAmount = MathUtils.min(
    261
          amount,
    262
          hub.previewRemoveByShares(assetId, userPosition.suppliedShares)
    263
        );
    264
        uint256 withdrawnShares = hub.remove(assetId, withdrawnAmount, msg.sender);
    265
    266
        userPosition.suppliedShares -= withdrawnShares.toUint120();
    267
    268
        if (_positionStatus[onBehalfOf].isUsingAsCollateral(reserveId)) {
    269
          uint256 newRiskPremium = _refreshAndValidateUserAccountData(onBehalfOf).riskPremium;
    270
          _notifyRiskPremiumUpdate(onBehalfOf, newRiskPremium);
    271
        }
    272
    273
        emit Withdraw(reserveId, msg.sender, onBehalfOf, withdrawnShares, withdrawnAmount);
    274
    275
        return (withdrawnShares, withdrawnAmount);
    276
      }
    277
    278
      /// @inheritdoc ISpokeBase
    279
      function borrow(
    280
        uint256 reserveId,
    281
        uint256 amount,
    282
        address onBehalfOf
    283
      ) external onlyPositionManager(onBehalfOf) returns (uint256, uint256) {
    284
        Reserve storage reserve = _getReserve(reserveId);
    285
        UserPosition storage userPosition = _userPositions[onBehalfOf][reserveId];
    286
        PositionStatus storage positionStatus = _positionStatus[onBehalfOf];
    287
        _validateBorrow(reserve.flags);
    288
        IHubBase hub = reserve.hub;
    289
    290
        uint256 drawnShares = hub.draw(reserve.assetId, amount, msg.sender);
    291
        userPosition.drawnShares += drawnShares.toUint120();
    292
        if (!positionStatus.isBorrowing(reserveId)) {
    293
          positionStatus.setBorrowing(reserveId, true);
    294
        }
    295
    296
        uint256 newRiskPremium = _refreshAndValidateUserAccountData(onBehalfOf).riskPremium;
    297
        _notifyRiskPremiumUpdate(onBehalfOf, newRiskPremium);
    298
    299
        emit Borrow(reserveId, msg.sender, onBehalfOf, drawnShares, amount);
    300
    301
        return (drawnShares, amount);
    302
      }
    303
    304
      /// @inheritdoc ISpokeBase
    305
      function repay(
    306
        uint256 reserveId,
    307
        uint256 amount,
    308
        address onBehalfOf
    309
      ) external onlyPositionManager(onBehalfOf) returns (uint256, uint256) {
    310
        Reserve storage reserve = _getReserve(reserveId);
    311
        UserPosition storage userPosition = _userPositions[onBehalfOf][reserveId];
    312
        _validateRepay(reserve.flags);
    313
    314
        uint256 drawnIndex = reserve.hub.getAssetDrawnIndex(reserve.assetId);
    315
        (uint256 drawnDebtRestored, uint256 premiumDebtRayRestored) = userPosition
    316
          .calculateRestoreAmount(drawnIndex, amount);
    317
        uint256 restoredShares = drawnDebtRestored.rayDivDown(drawnIndex);
    318
    319
        IHubBase.PremiumDelta memory premiumDelta = userPosition.getPremiumDelta({
    320
          drawnSharesTaken: restoredShares,
    321
          drawnIndex: drawnIndex,
    322
          riskPremium: _positionStatus[onBehalfOf].riskPremium,
    323
          restoredPremiumRay: premiumDebtRayRestored
    324
        });
    325
    326
        uint256 totalDebtRestored = drawnDebtRestored + premiumDebtRayRestored.fromRayUp();
    327
        IERC20(reserve.underlying).safeTransferFrom(
    328
          msg.sender,
    329
          address(reserve.hub),
    330
          totalDebtRestored
    331
        );
    332
        reserve.hub.restore(reserve.assetId, drawnDebtRestored, premiumDelta);
    333
    334
        userPosition.applyPremiumDelta(premiumDelta);
    335
        userPosition.drawnShares -= restoredShares.toUint120();
    336
        if (userPosition.drawnShares == 0) {
    337
          PositionStatus storage positionStatus = _positionStatus[onBehalfOf];
    338
          positionStatus.setBorrowing(reserveId, false);
    339
        }
    340
    341
        emit Repay(reserveId, msg.sender, onBehalfOf, restoredShares, totalDebtRestored, premiumDelta);
    342
    343
        return (restoredShares, totalDebtRestored);
    344
      }
    345
    346
      /// @inheritdoc ISpokeBase
    347
      function liquidationCall(
    348
        uint256 collateralReserveId,
    349
        uint256 debtReserveId,
    350
        address user,
    351
        uint256 debtToCover,
    352
        bool receiveShares
    353
      ) external {
    354
        Reserve storage collateralReserve = _getReserve(collateralReserveId);
    355
        Reserve storage debtReserve = _getReserve(debtReserveId);
    356
        DynamicReserveConfig storage collateralDynConfig = _dynamicConfig[collateralReserveId][
    357
          _userPositions[user][collateralReserveId].dynamicConfigKey
    358
        ];
    359
        UserAccountData memory userAccountData = _calculateUserAccountData(user);
    360
    361
        uint256 drawnIndex = debtReserve.hub.getAssetDrawnIndex(debtReserve.assetId);
    362
        (uint256 drawnDebt, uint256 premiumDebtRay) = _userPositions[user][debtReserveId].getDebt(
    363
          drawnIndex
    364
        );
    365
    366
        LiquidationLogic.LiquidateUserParams memory params = LiquidationLogic.LiquidateUserParams({
    367
          collateralReserveId: collateralReserveId,
    368
          debtReserveId: debtReserveId,
    369
          oracle: ORACLE,
    370
          user: user,
    371
          debtToCover: debtToCover,
    372
          healthFactor: userAccountData.healthFactor,
    373
          drawnDebt: drawnDebt,
    374
          premiumDebtRay: premiumDebtRay,
    375
          drawnIndex: drawnIndex,
    376
          totalDebtValue: userAccountData.totalDebtValue,
    377
          activeCollateralCount: userAccountData.activeCollateralCount,
    378
          borrowedCount: userAccountData.borrowedCount,
    379
          liquidator: msg.sender,
    380
          receiveShares: receiveShares
    381
        });
    382
    383
        bool isUserInDeficit = LiquidationLogic.liquidateUser(
    384
          collateralReserve,
    385
          debtReserve,
    386
          _userPositions,
    387
          _positionStatus,
    388
          _liquidationConfig,
    389
          collateralDynConfig,
    390
          params
    391
        );
    392
    393
        uint256 newRiskPremium = 0;
    394
        if (isUserInDeficit) {
    395
          _reportDeficit(user);
    396
        } else {
    397
          newRiskPremium = _calculateUserAccountData(user).riskPremium;
    398
        }
    399
        _notifyRiskPremiumUpdate(user, newRiskPremium);
    400
      }
    401
    402
      /// @inheritdoc ISpoke
    403
      function setUsingAsCollateral(
    404
        uint256 reserveId,
    405
        bool usingAsCollateral,
    406
        address onBehalfOf
    407
      ) external onlyPositionManager(onBehalfOf) {
    408
        _validateSetUsingAsCollateral(_getReserve(reserveId).flags, usingAsCollateral);
    409
        PositionStatus storage positionStatus = _positionStatus[onBehalfOf];
    410
    411
        if (positionStatus.isUsingAsCollateral(reserveId) == usingAsCollateral) {
    412
          return;
    413
        }
    414
        positionStatus.setUsingAsCollateral(reserveId, usingAsCollateral);
    415
    416
        if (usingAsCollateral) {
    417
          _refreshDynamicConfig(onBehalfOf, reserveId);
    418
        } else {
    419
          uint256 newRiskPremium = _refreshAndValidateUserAccountData(onBehalfOf).riskPremium;
    420
          _notifyRiskPremiumUpdate(onBehalfOf, newRiskPremium);
    421
        }
    422
    423
        emit SetUsingAsCollateral(reserveId, msg.sender, onBehalfOf, usingAsCollateral);
    424
      }
    425
    426
      /// @inheritdoc ISpoke
    427
      function updateUserRiskPremium(address onBehalfOf) external {
    428
        if (!_isPositionManager({user: onBehalfOf, manager: msg.sender})) {
    429
          _checkCanCall(msg.sender, msg.data);
    430
        }
    431
        uint256 newRiskPremium = _calculateUserAccountData(onBehalfOf).riskPremium;
    432
        _notifyRiskPremiumUpdate(onBehalfOf, newRiskPremium);
    433
      }
    434
    435
      /// @inheritdoc ISpoke
    436
      function updateUserDynamicConfig(address onBehalfOf) external {
    437
        if (!_isPositionManager({user: onBehalfOf, manager: msg.sender})) {
    438
          _checkCanCall(msg.sender, msg.data);
    439
        }
    440
        uint256 newRiskPremium = _refreshAndValidateUserAccountData(onBehalfOf).riskPremium;
    441
        _notifyRiskPremiumUpdate(onBehalfOf, newRiskPremium);
    442
      }
    443
    444
      /// @inheritdoc ISpoke
    445
      function setUserPositionManager(address positionManager, bool approve) external {
    446
        _setUserPositionManager({positionManager: positionManager, user: msg.sender, approve: approve});
    447
      }
    448
    449
      /// @inheritdoc ISpoke
    450
      function setUserPositionManagerWithSig(
    451
        address positionManager,
    452
        address user,
    453
        bool approve,
    454
        uint256 nonce,
    455
        uint256 deadline,
    456
        bytes calldata signature
    457
      ) external {
    458
        require(block.timestamp <= deadline, InvalidSignature());
    459
        bytes32 digest = _hashTypedData(
    460
          keccak256(
    461
            abi.encode(
    462
              SET_USER_POSITION_MANAGER_TYPEHASH,
    463
              positionManager,
    464
              user,
    465
              approve,
    466
              nonce,
    467
              deadline
    468
            )
    469
          )
    470
        );
    471
        require(SignatureChecker.isValidSignatureNow(user, digest, signature), InvalidSignature());
    472
        _useCheckedNonce(user, nonce);
    473
        _setUserPositionManager({positionManager: positionManager, user: user, approve: approve});
    474
      }
    475
    476
      /// @inheritdoc ISpoke
    477
      function renouncePositionManagerRole(address onBehalfOf) external {
    478
        if (!_positionManager[msg.sender].approval[onBehalfOf]) {
    479
          return;
    480
        }
    481
        _positionManager[msg.sender].approval[onBehalfOf] = false;
    482
        emit SetUserPositionManager(onBehalfOf, msg.sender, false);
    483
      }
    484
    485
      /// @inheritdoc ISpoke
    486
      function permitReserve(
    487
        uint256 reserveId,
    488
        address onBehalfOf,
    489
        uint256 value,
    490
        uint256 deadline,
    491
        uint8 permitV,
    492
        bytes32 permitR,
    493
        bytes32 permitS
    494
      ) external {
    495
        Reserve storage reserve = _reserves[reserveId];
    496
        address underlying = reserve.underlying;
    497
        require(underlying != address(0), ReserveNotListed());
    498
        try
    499
          IERC20Permit(underlying).permit({
    500
            owner: onBehalfOf,
    501
            spender: address(this),
    502
            value: value,
    503
            deadline: deadline,
    504
            v: permitV,
    505
            r: permitR,
    506
            s: permitS
    507
          })
    508
        {} catch {}
    509
      }
    510
    511
      /// @inheritdoc ISpoke
    512
      function getLiquidationConfig() external view returns (LiquidationConfig memory) {
    513
        return _liquidationConfig;
    514
      }
    515
    516
      /// @inheritdoc ISpoke
    517
      function getReserveCount() external view returns (uint256) {
    518
        return _reserveCount;
    519
      }
    520
    521
      /// @inheritdoc ISpokeBase
    522
      function getReserveSuppliedAssets(uint256 reserveId) external view returns (uint256) {
    523
        Reserve storage reserve = _getReserve(reserveId);
    524
        return reserve.hub.getSpokeAddedAssets(reserve.assetId, address(this));
    525
      }
    526
    527
      /// @inheritdoc ISpokeBase
    528
      function getReserveSuppliedShares(uint256 reserveId) external view returns (uint256) {
    529
        Reserve storage reserve = _getReserve(reserveId);
    530
        return reserve.hub.getSpokeAddedShares(reserve.assetId, address(this));
    531
      }
    532
    533
      /// @inheritdoc ISpokeBase
    534
      function getReserveDebt(uint256 reserveId) external view returns (uint256, uint256) {
    535
        Reserve storage reserve = _getReserve(reserveId);
    536
        return reserve.hub.getSpokeOwed(reserve.assetId, address(this));
    537
      }
    538
    539
      /// @inheritdoc ISpokeBase
    540
      function getReserveTotalDebt(uint256 reserveId) external view returns (uint256) {
    541
        Reserve storage reserve = _getReserve(reserveId);
    542
        return reserve.hub.getSpokeTotalOwed(reserve.assetId, address(this));
    543
      }
    544
    545
      /// @inheritdoc ISpoke
    546
      function getReserve(uint256 reserveId) external view returns (Reserve memory) {
    547
        return _getReserve(reserveId);
    548
      }
    549
    550
      /// @inheritdoc ISpoke
    551
      function getReserveConfig(uint256 reserveId) external view returns (ReserveConfig memory) {
    552
        Reserve storage reserve = _getReserve(reserveId);
    553
        return
    554
          ReserveConfig({
    555
            collateralRisk: reserve.collateralRisk,
    556
            paused: reserve.flags.paused(),
    557
            frozen: reserve.flags.frozen(),
    558
            borrowable: reserve.flags.borrowable(),
    559
            liquidatable: reserve.flags.liquidatable(),
    560
            receiveSharesEnabled: reserve.flags.receiveSharesEnabled()
    561
          });
    562
      }
    563
    564
      /// @inheritdoc ISpoke
    565
      function getDynamicReserveConfig(
    566
        uint256 reserveId,
    567
        uint24 dynamicConfigKey
    568
      ) external view returns (DynamicReserveConfig memory) {
    569
        _getReserve(reserveId);
    570
        return _dynamicConfig[reserveId][dynamicConfigKey];
    571
      }
    572
    573
      /// @inheritdoc ISpoke
    574
      function getUserReserveStatus(
    575
        uint256 reserveId,
    576
        address user
    577
      ) external view returns (bool, bool) {
    578
        _getReserve(reserveId);
    579
        PositionStatus storage positionStatus = _positionStatus[user];
    580
        return (positionStatus.isUsingAsCollateral(reserveId), positionStatus.isBorrowing(reserveId));
    581
      }
    582
    583
      /// @inheritdoc ISpokeBase
    584
      function getUserSuppliedAssets(uint256 reserveId, address user) external view returns (uint256) {
    585
        Reserve storage reserve = _getReserve(reserveId);
    586
        return
    587
          reserve.hub.previewRemoveByShares(
    588
            reserve.assetId,
    589
            _userPositions[user][reserveId].suppliedShares
    590
          );
    591
      }
    592
    593
      /// @inheritdoc ISpokeBase
    594
      function getUserSuppliedShares(uint256 reserveId, address user) external view returns (uint256) {
    595
        _getReserve(reserveId);
    596
        return _userPositions[user][reserveId].suppliedShares;
    597
      }
    598
    599
      /// @inheritdoc ISpokeBase
    600
      function getUserDebt(uint256 reserveId, address user) external view returns (uint256, uint256) {
    601
        Reserve storage reserve = _getReserve(reserveId);
    602
        UserPosition storage userPosition = _userPositions[user][reserveId];
    603
        (uint256 drawnDebt, uint256 premiumDebtRay) = userPosition.getDebt(
    604
          reserve.hub,
    605
          reserve.assetId
    606
        );
    607
        return (drawnDebt, premiumDebtRay.fromRayUp());
    608
      }
    609
    610
      /// @inheritdoc ISpokeBase
    611
      function getUserTotalDebt(uint256 reserveId, address user) external view returns (uint256) {
    612
        Reserve storage reserve = _getReserve(reserveId);
    613
        UserPosition storage userPosition = _userPositions[user][reserveId];
    614
        (uint256 drawnDebt, uint256 premiumDebtRay) = userPosition.getDebt(
    615
          reserve.hub,
    616
          reserve.assetId
    617
        );
    618
        return (drawnDebt + premiumDebtRay.fromRayUp());
    619
      }
    620
    621
      /// @inheritdoc ISpokeBase
    622
      function getUserPremiumDebtRay(uint256 reserveId, address user) external view returns (uint256) {
    623
        Reserve storage reserve = _getReserve(reserveId);
    624
        UserPosition storage userPosition = _userPositions[user][reserveId];
    625
        (, uint256 premiumDebtRay) = userPosition.getDebt(reserve.hub, reserve.assetId);
    626
        return premiumDebtRay;
    627
      }
    628
    629
      /// @inheritdoc ISpoke
    630
      function getUserPosition(
    631
        uint256 reserveId,
    632
        address user
    633
      ) external view returns (UserPosition memory) {
    634
        _getReserve(reserveId);
    635
        return _userPositions[user][reserveId];
    636
      }
    637
    638
      /// @inheritdoc ISpoke
    639
      function getUserLastRiskPremium(address user) external view returns (uint256) {
    640
        return _positionStatus[user].riskPremium;
    641
      }
    642
    643
      /// @inheritdoc ISpoke
    644
      function getUserAccountData(address user) external view returns (UserAccountData memory) {
    645
        // SAFETY: function does not modify state when `refreshConfig` is false.
    646
        return _castToView(_processUserAccountData)(user, false);
    647
      }
    648
    649
      /// @inheritdoc ISpoke
    650
      function getLiquidationBonus(
    651
        uint256 reserveId,
    652
        address user,
    653
        uint256 healthFactor
    654
      ) external view returns (uint256) {
    655
        _getReserve(reserveId);
    656
        return
    657
          LiquidationLogic.calculateLiquidationBonus({
    658
            healthFactorForMaxBonus: _liquidationConfig.healthFactorForMaxBonus,
    659
            liquidationBonusFactor: _liquidationConfig.liquidationBonusFactor,
    660
            healthFactor: healthFactor,
    661
            maxLiquidationBonus: _dynamicConfig[reserveId][
    662
              _userPositions[user][reserveId].dynamicConfigKey
    663
            ].maxLiquidationBonus
    664
          });
    665
      }
    666
    667
      /// @inheritdoc ISpoke
    668
      function isPositionManagerActive(address positionManager) external view returns (bool) {
    669
        return _positionManager[positionManager].active;
    670
      }
    671
    672
      /// @inheritdoc ISpoke
    673
      function isPositionManager(address user, address positionManager) external view returns (bool) {
    674
        return _isPositionManager(user, positionManager);
    675
      }
    676
    677
      /// @inheritdoc ISpoke
    678
      function DOMAIN_SEPARATOR() external view returns (bytes32) {
    679
        return _domainSeparator();
    680
      }
    681
    682
      /// @inheritdoc ISpoke
    683
      function getLiquidationLogic() external pure returns (address) {
    684
        return address(LiquidationLogic);
    685
      }
    686
    687
      function _updateReservePriceSource(uint256 reserveId, address priceSource) internal {
    688
        require(priceSource != address(0), InvalidAddress());
    689
        IAaveOracle(ORACLE).setReserveSource(reserveId, priceSource);
    690
        emit UpdateReservePriceSource(reserveId, priceSource);
    691
      }
    692
    693
      function _setUserPositionManager(address positionManager, address user, bool approve) internal {
    694
        PositionManagerConfig storage config = _positionManager[positionManager];
    695
        // only allow approval when position manager is active for improved UX
    696
        require(!approve || config.active, InactivePositionManager());
    697
        config.approval[user] = approve;
    698
        emit SetUserPositionManager(user, positionManager, approve);
    699
      }
    700
    701
      /// @notice Calculates and validates the user account data.
    702
      /// @dev It refreshes the dynamic config before calculation.
    703
      /// @dev It checks that the health factor is above the liquidation threshold.
    704
      function _refreshAndValidateUserAccountData(
    705
        address user
    706
      ) internal returns (UserAccountData memory) {
    707
        UserAccountData memory accountData = _processUserAccountData(user, true);
    708
        emit RefreshAllUserDynamicConfig(user);
    709
        require(
    710
          accountData.healthFactor >= HEALTH_FACTOR_LIQUIDATION_THRESHOLD,
    711
          HealthFactorBelowThreshold()
    712
        );
    713
        return accountData;
    714
      }
    715
    716
      /// @notice Calculates the user account data with the current user dynamic config.
    717
      function _calculateUserAccountData(address user) internal returns (UserAccountData memory) {
    718
        return _processUserAccountData(user, false); // does not modify state
    719
      }
    720
    721
      /// @notice Process the user account data and updates dynamic config of the user if `refreshConfig` is true.
    722
      function _processUserAccountData(
    723
        address user,
    724
        bool refreshConfig
    725
      ) internal returns (UserAccountData memory accountData) {
    726
        PositionStatus storage positionStatus = _positionStatus[user];
    727
    728
        uint256 reserveId = _reserveCount;
    729
        KeyValueList.List memory collateralInfo = KeyValueList.init(
    730
          positionStatus.collateralCount(reserveId)
    731
        );
    732
        bool borrowing;
    733
        bool collateral;
    734
        while (true) {
    735
          (reserveId, borrowing, collateral) = positionStatus.next(reserveId);
    736
          if (reserveId == PositionStatusMap.NOT_FOUND) break;
    737
    738
          UserPosition storage userPosition = _userPositions[user][reserveId];
    739
          Reserve storage reserve = _reserves[reserveId];
    740
    741
          uint256 assetPrice = IAaveOracle(ORACLE).getReservePrice(reserveId);
    742
          uint256 assetUnit = MathUtils.uncheckedExp(10, reserve.decimals);
    743
    744
          if (collateral) {
    745
            uint256 collateralFactor = _dynamicConfig[reserveId][
    746
              refreshConfig
    747
                ? (userPosition.dynamicConfigKey = reserve.dynamicConfigKey)
    748
                : userPosition.dynamicConfigKey
    749
            ].collateralFactor;
    750
            if (collateralFactor > 0) {
    751
              uint256 suppliedShares = userPosition.suppliedShares;
    752
              if (suppliedShares > 0) {
    753
                // cannot round down to zero
    754
                uint256 userCollateralValue = (reserve.hub.previewRemoveByShares(
    755
                  reserve.assetId,
    756
                  suppliedShares
    757
                ) * assetPrice).wadDivDown(assetUnit);
    758
                accountData.totalCollateralValue += userCollateralValue;
    759
                collateralInfo.add(
    760
                  accountData.activeCollateralCount,
    761
                  reserve.collateralRisk,
    762
                  userCollateralValue
    763
                );
    764
                accountData.avgCollateralFactor += collateralFactor * userCollateralValue;
    765
                accountData.activeCollateralCount = accountData.activeCollateralCount.uncheckedAdd(1);
    766
              }
    767
            }
    768
          }
    769
    770
          if (borrowing) {
    771
            (uint256 drawnDebt, uint256 premiumDebtRay) = userPosition.getDebt(
    772
              reserve.hub,
    773
              reserve.assetId
    774
            );
    775
            // we can simplify since there is no precision loss due to the division here
    776
            accountData.totalDebtValue += ((drawnDebt + premiumDebtRay.fromRayUp()) * assetPrice)
    777
              .wadDivUp(assetUnit);
    778
            accountData.borrowedCount = accountData.borrowedCount.uncheckedAdd(1);
    779
          }
    780
        }
    781
    782
        if (accountData.totalDebtValue > 0) {
    783
          // at this point, `avgCollateralFactor` is the collateral-weighted sum (scaled by `collateralFactor` in BPS)
    784
          // health factor uses this directly for simplicity
    785
          // the division by `totalCollateralValue` to compute the weighted average is done later
    786
          accountData.healthFactor = accountData
    787
            .avgCollateralFactor
    788
            .wadDivDown(accountData.totalDebtValue)
    789
            .fromBpsDown();
    790
        } else {
    791
          accountData.healthFactor = type(uint256).max;
    792
        }
    793
    794
        if (accountData.totalCollateralValue > 0) {
    795
          accountData.avgCollateralFactor = accountData
    796
            .avgCollateralFactor
    797
            .wadDivDown(accountData.totalCollateralValue)
    798
            .fromBpsDown();
    799
        }
    800
    801
        // sort by collateral risk in ASC, collateral value in DESC
    802
        collateralInfo.sortByKey();
    803
    804
        // runs until either the collateral or debt is exhausted
    805
        uint256 debtValueLeftToCover = accountData.totalDebtValue;
    806
    807
        for (uint256 index = 0; index < collateralInfo.length(); ++index) {
    808
          if (debtValueLeftToCover == 0) {
    809
            break;
    810
          }
    811
    812
          (uint256 collateralRisk, uint256 userCollateralValue) = collateralInfo.get(index);
    813
          userCollateralValue = userCollateralValue.min(debtValueLeftToCover);
    814
          accountData.riskPremium += userCollateralValue * collateralRisk;
    815
          debtValueLeftToCover = debtValueLeftToCover.uncheckedSub(userCollateralValue);
    816
        }
    817
    818
        if (debtValueLeftToCover < accountData.totalDebtValue) {
    819
          accountData.riskPremium /= accountData.totalDebtValue.uncheckedSub(debtValueLeftToCover);
    820
        }
    821
    822
        return accountData;
    823
      }
    824
    825
      function _refreshDynamicConfig(address user, uint256 reserveId) internal {
    826
        _userPositions[user][reserveId].dynamicConfigKey = _reserves[reserveId].dynamicConfigKey;
    827
        emit RefreshSingleUserDynamicConfig(user, reserveId);
    828
      }
    829
    830
      /// @notice Refreshes premium for borrowed reserves of `user` with `newRiskPremium`.
    831
      /// @dev Skips the refresh if the user risk premium remains zero.
    832
      function _notifyRiskPremiumUpdate(address user, uint256 newRiskPremium) internal {
    833
        PositionStatus storage positionStatus = _positionStatus[user];
    834
        if (newRiskPremium == 0 && positionStatus.riskPremium == 0) {
    835
          return;
    836
        }
    837
        positionStatus.riskPremium = newRiskPremium.toUint24();
    838
    839
        uint256 reserveId = _reserveCount;
    840
        while ((reserveId = positionStatus.nextBorrowing(reserveId)) != PositionStatusMap.NOT_FOUND) {
    841
          UserPosition storage userPosition = _userPositions[user][reserveId];
    842
          Reserve storage reserve = _reserves[reserveId];
    843
          uint256 assetId = reserve.assetId;
    844
          IHubBase hub = reserve.hub;
    845
    846
          IHubBase.PremiumDelta memory premiumDelta = userPosition.getPremiumDelta({
    847
            drawnSharesTaken: 0,
    848
            drawnIndex: hub.getAssetDrawnIndex(assetId),
    849
            riskPremium: newRiskPremium,
    850
            restoredPremiumRay: 0
    851
          });
    852
    853
          hub.refreshPremium(assetId, premiumDelta);
    854
          userPosition.applyPremiumDelta(premiumDelta);
    855
          emit RefreshPremiumDebt(reserveId, user, premiumDelta);
    856
        }
    857
        emit UpdateUserRiskPremium(user, newRiskPremium);
    858
      }
    859
    860
      /// @notice Reports deficits for all debt reserves of the user, including the reserve being repaid during liquidation.
    861
      /// @dev Deficit validation should already have occurred during liquidation.
    862
      /// @dev It clears the user position, setting drawn debt, premium debt, and risk premium to zero.
    863
      function _reportDeficit(address user) internal {
    864
        PositionStatus storage positionStatus = _positionStatus[user];
    865
    866
        uint256 reserveId = _reserveCount;
    867
        while ((reserveId = positionStatus.nextBorrowing(reserveId)) != PositionStatusMap.NOT_FOUND) {
    868
          UserPosition storage userPosition = _userPositions[user][reserveId];
    869
          Reserve storage reserve = _reserves[reserveId];
    870
          IHubBase hub = reserve.hub;
    871
          uint256 assetId = reserve.assetId;
    872
    873
          uint256 drawnIndex = hub.getAssetDrawnIndex(assetId);
    874
          (uint256 drawnDebtReported, uint256 premiumDebtRay) = userPosition.getDebt(drawnIndex);
    875
          uint256 deficitShares = drawnDebtReported.rayDivDown(drawnIndex);
    876
    877
          IHubBase.PremiumDelta memory premiumDelta = userPosition.getPremiumDelta({
    878
            drawnSharesTaken: deficitShares,
    879
            drawnIndex: drawnIndex,
    880
            riskPremium: 0,
    881
            restoredPremiumRay: premiumDebtRay
    882
          });
    883
    884
          hub.reportDeficit(assetId, drawnDebtReported, premiumDelta);
    885
          userPosition.applyPremiumDelta(premiumDelta);
    886
          userPosition.drawnShares -= deficitShares.toUint120();
    887
          positionStatus.setBorrowing(reserveId, false);
    888
    889
          emit ReportDeficit(reserveId, user, deficitShares, premiumDelta);
    890
        }
    891
      }
    892
    893
      function _getReserve(uint256 reserveId) internal view returns (Reserve storage) {
    894
        Reserve storage reserve = _reserves[reserveId];
    895
        require(address(reserve.hub) != address(0), ReserveNotListed());
    896
        return reserve;
    897
      }
    898
    899
      /// @dev CollateralFactor of historical config keys cannot be 0, which allows liquidations to proceed.
    900
      function _validateUpdateDynamicReserveConfig(
    901
        DynamicReserveConfig storage currentConfig,
    902
        DynamicReserveConfig calldata newConfig
    903
      ) internal view {
    904
        // sufficient check since maxLiquidationBonus is always >= 100_00
    905
        require(currentConfig.maxLiquidationBonus > 0, ConfigKeyUninitialized());
    906
        require(newConfig.collateralFactor > 0, InvalidCollateralFactor());
    907
        _validateDynamicReserveConfig(newConfig);
    908
      }
    909
    910
      function _validateSupply(ReserveFlags flags) internal pure {
    911
        require(!flags.paused(), ReservePaused());
    912
        require(!flags.frozen(), ReserveFrozen());
    913
      }
    914
    915
      function _validateWithdraw(ReserveFlags flags) internal pure {
    916
        require(!flags.paused(), ReservePaused());
    917
      }
    918
    919
      function _validateBorrow(ReserveFlags flags) internal pure {
    920
        require(!flags.paused(), ReservePaused());
    921
        require(!flags.frozen(), ReserveFrozen());
    922
        require(flags.borrowable(), ReserveNotBorrowable());
    923
        // health factor is checked at the end of borrow action
    924
      }
    925
    926
      function _validateRepay(ReserveFlags flags) internal pure {
    927
        require(!flags.paused(), ReservePaused());
    928
      }
    929
    930
      function _validateSetUsingAsCollateral(ReserveFlags flags, bool usingAsCollateral) internal pure {
    931
        require(!flags.paused(), ReservePaused());
    932
        // can disable as collateral if the reserve is frozen
    933
        require(!usingAsCollateral || !flags.frozen(), ReserveFrozen());
    934
      }
    935
    936
      /// @notice Returns whether `manager` is active & approved positionManager for `user`.
    937
      function _isPositionManager(address user, address manager) internal view returns (bool) {
    938
        if (user == manager) return true;
    939
        PositionManagerConfig storage config = _positionManager[manager];
    940
        return config.active && config.approval[user];
    941
      }
    942
    943
      function _validateReserveConfig(ReserveConfig calldata config) internal pure {
    944
        require(config.collateralRisk <= MAX_ALLOWED_COLLATERAL_RISK, InvalidCollateralRisk());
    945
      }
    946
    947
      /// @dev Enforces compatible `maxLiquidationBonus` and `collateralFactor` so at the moment debt is created
    948
      /// there is enough collateral to cover liquidation.
    949
      function _validateDynamicReserveConfig(DynamicReserveConfig calldata config) internal pure {
    950
        require(
    951
          config.collateralFactor < PercentageMath.PERCENTAGE_FACTOR &&
    952
            config.maxLiquidationBonus >= PercentageMath.PERCENTAGE_FACTOR &&
    953
            config.maxLiquidationBonus.percentMulUp(config.collateralFactor) <
    954
            PercentageMath.PERCENTAGE_FACTOR,
    955
          InvalidCollateralFactorAndMaxLiquidationBonus()
    956
        );
    957
        require(config.liquidationFee <= PercentageMath.PERCENTAGE_FACTOR, InvalidLiquidationFee());
    958
      }
    959
    960
      function _domainNameAndVersion() internal pure override returns (string memory, string memory) {
    961
        return ('Spoke', '1');
    962
      }
    963
    964
      function _castToView(
    965
        function(address, bool) internal returns (UserAccountData memory) fnIn
    966
      )
    967
        internal
    968
        pure
    969
        returns (function(address, bool) internal view returns (UserAccountData memory) fnOut)
    970
      {
    971
        assembly ('memory-safe') {
    972
          fnOut := fnIn
    973
        }
    974
      }
    975
    }
    976
    0.0% src/spoke/SpokeConfigurator.sol
    Lines covered: 0 / 128 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity 0.8.28;
    4
    5
    import {SafeCast} from 'src/dependencies/openzeppelin/SafeCast.sol';
    6
    import {Ownable2Step, Ownable} from 'src/dependencies/openzeppelin/Ownable2Step.sol';
    7
    import {ISpoke} from 'src/spoke/interfaces/ISpoke.sol';
    8
    import {ISpokeConfigurator} from 'src/spoke/interfaces/ISpokeConfigurator.sol';
    9
    10
    /// @title SpokeConfigurator
    11
    /// @author Aave Labs
    12
    /// @notice Handles administrative functions on the spoke.
    13
    /// @dev Must be granted permission by the spoke.
    14
    contract SpokeConfigurator is Ownable2Step, ISpokeConfigurator {
    15
      using SafeCast for uint256;
    16
    17
      mapping(address spoke => uint256) internal _maxReserves;
    18
    19
      /// @dev Constructor.
    20
      /// @param owner_ The address of the owner.
    21
      constructor(address owner_) Ownable(owner_) {}
    22
    23
      /// @inheritdoc ISpokeConfigurator
    24
      function updateReservePriceSource(
    25
        address spoke,
    26
        uint256 reserveId,
    27
        address priceSource
    28
      ) external onlyOwner {
    29
        ISpoke(spoke).updateReservePriceSource(reserveId, priceSource);
    30
      }
    31
    32
      /// @inheritdoc ISpokeConfigurator
    33
      function updateLiquidationTargetHealthFactor(
    34
        address spoke,
    35
        uint256 targetHealthFactor
    36
      ) external onlyOwner {
    37
        ISpoke targetSpoke = ISpoke(spoke);
    38
        ISpoke.LiquidationConfig memory liquidationConfig = targetSpoke.getLiquidationConfig();
    39
        liquidationConfig.targetHealthFactor = targetHealthFactor.toUint128();
    40
        targetSpoke.updateLiquidationConfig(liquidationConfig);
    41
      }
    42
    43
      /// @inheritdoc ISpokeConfigurator
    44
      function updateHealthFactorForMaxBonus(
    45
        address spoke,
    46
        uint256 healthFactorForMaxBonus
    47
      ) external onlyOwner {
    48
        ISpoke targetSpoke = ISpoke(spoke);
    49
        ISpoke.LiquidationConfig memory liquidationConfig = targetSpoke.getLiquidationConfig();
    50
        liquidationConfig.healthFactorForMaxBonus = healthFactorForMaxBonus.toUint64();
    51
        targetSpoke.updateLiquidationConfig(liquidationConfig);
    52
      }
    53
    54
      /// @inheritdoc ISpokeConfigurator
    55
      function updateLiquidationBonusFactor(
    56
        address spoke,
    57
        uint256 liquidationBonusFactor
    58
      ) external onlyOwner {
    59
        ISpoke targetSpoke = ISpoke(spoke);
    60
        ISpoke.LiquidationConfig memory liquidationConfig = targetSpoke.getLiquidationConfig();
    61
        liquidationConfig.liquidationBonusFactor = liquidationBonusFactor.toUint16();
    62
        targetSpoke.updateLiquidationConfig(liquidationConfig);
    63
      }
    64
    65
      /// @inheritdoc ISpokeConfigurator
    66
      function updateLiquidationConfig(
    67
        address spoke,
    68
        ISpoke.LiquidationConfig calldata liquidationConfig
    69
      ) external onlyOwner {
    70
        ISpoke(spoke).updateLiquidationConfig(liquidationConfig);
    71
      }
    72
    73
      /// @inheritdoc ISpokeConfigurator
    74
      function updateMaxReserves(address spoke, uint256 maxReserves) external onlyOwner {
    75
        _maxReserves[spoke] = maxReserves;
    76
        emit UpdateMaxReserves(spoke, maxReserves);
    77
      }
    78
    79
      /// @inheritdoc ISpokeConfigurator
    80
      function addReserve(
    81
        address spoke,
    82
        address hub,
    83
        uint256 assetId,
    84
        address priceSource,
    85
        ISpoke.ReserveConfig calldata config,
    86
        ISpoke.DynamicReserveConfig calldata dynamicConfig
    87
      ) external onlyOwner returns (uint256) {
    88
        require(
    89
          ISpoke(spoke).getReserveCount() < _maxReserves[spoke],
    90
          MaximumReservesReached(spoke, _maxReserves[spoke])
    91
        );
    92
        return ISpoke(spoke).addReserve(hub, assetId, priceSource, config, dynamicConfig);
    93
      }
    94
    95
      /// @inheritdoc ISpokeConfigurator
    96
      function updatePaused(address spoke, uint256 reserveId, bool paused) external onlyOwner {
    97
        ISpoke targetSpoke = ISpoke(spoke);
    98
        ISpoke.ReserveConfig memory reserveConfig = targetSpoke.getReserveConfig(reserveId);
    99
        reserveConfig.paused = paused;
    100
        targetSpoke.updateReserveConfig(reserveId, reserveConfig);
    101
      }
    102
    103
      /// @inheritdoc ISpokeConfigurator
    104
      function updateFrozen(address spoke, uint256 reserveId, bool frozen) external onlyOwner {
    105
        ISpoke targetSpoke = ISpoke(spoke);
    106
        ISpoke.ReserveConfig memory reserveConfig = targetSpoke.getReserveConfig(reserveId);
    107
        reserveConfig.frozen = frozen;
    108
        targetSpoke.updateReserveConfig(reserveId, reserveConfig);
    109
      }
    110
    111
      /// @inheritdoc ISpokeConfigurator
    112
      function updateBorrowable(address spoke, uint256 reserveId, bool borrowable) external onlyOwner {
    113
        ISpoke targetSpoke = ISpoke(spoke);
    114
        ISpoke.ReserveConfig memory reserveConfig = targetSpoke.getReserveConfig(reserveId);
    115
        reserveConfig.borrowable = borrowable;
    116
        targetSpoke.updateReserveConfig(reserveId, reserveConfig);
    117
      }
    118
    119
      /// @inheritdoc ISpokeConfigurator
    120
      function updateLiquidatable(
    121
        address spoke,
    122
        uint256 reserveId,
    123
        bool liquidatable
    124
      ) external onlyOwner {
    125
        ISpoke targetSpoke = ISpoke(spoke);
    126
        ISpoke.ReserveConfig memory reserveConfig = targetSpoke.getReserveConfig(reserveId);
    127
        reserveConfig.liquidatable = liquidatable;
    128
        targetSpoke.updateReserveConfig(reserveId, reserveConfig);
    129
      }
    130
    131
      /// @inheritdoc ISpokeConfigurator
    132
      function updateReceiveSharesEnabled(
    133
        address spoke,
    134
        uint256 reserveId,
    135
        bool receiveSharesEnabled
    136
      ) external onlyOwner {
    137
        ISpoke targetSpoke = ISpoke(spoke);
    138
        ISpoke.ReserveConfig memory reserveConfig = targetSpoke.getReserveConfig(reserveId);
    139
        reserveConfig.receiveSharesEnabled = receiveSharesEnabled;
    140
        targetSpoke.updateReserveConfig(reserveId, reserveConfig);
    141
      }
    142
    143
      /// @inheritdoc ISpokeConfigurator
    144
      function updateCollateralRisk(
    145
        address spoke,
    146
        uint256 reserveId,
    147
        uint256 collateralRisk
    148
      ) external onlyOwner {
    149
        ISpoke targetSpoke = ISpoke(spoke);
    150
        ISpoke.ReserveConfig memory reserveConfig = targetSpoke.getReserveConfig(reserveId);
    151
        reserveConfig.collateralRisk = collateralRisk.toUint24();
    152
        targetSpoke.updateReserveConfig(reserveId, reserveConfig);
    153
      }
    154
    155
      /// @inheritdoc ISpokeConfigurator
    156
      function addCollateralFactor(
    157
        address spoke,
    158
        uint256 reserveId,
    159
        uint16 collateralFactor
    160
      ) external onlyOwner returns (uint24) {
    161
        ISpoke targetSpoke = ISpoke(spoke);
    162
        ISpoke.DynamicReserveConfig memory dynamicReserveConfig = targetSpoke.getDynamicReserveConfig(
    163
          reserveId,
    164
          _getReserveLastDynamicConfigKey(spoke, reserveId)
    165
        );
    166
        dynamicReserveConfig.collateralFactor = collateralFactor;
    167
        return targetSpoke.addDynamicReserveConfig(reserveId, dynamicReserveConfig);
    168
      }
    169
    170
      /// @inheritdoc ISpokeConfigurator
    171
      function updateCollateralFactor(
    172
        address spoke,
    173
        uint256 reserveId,
    174
        uint24 dynamicConfigKey,
    175
        uint16 collateralFactor
    176
      ) external onlyOwner {
    177
        ISpoke targetSpoke = ISpoke(spoke);
    178
        ISpoke.DynamicReserveConfig memory dynamicReserveConfig = targetSpoke.getDynamicReserveConfig(
    179
          reserveId,
    180
          dynamicConfigKey
    181
        );
    182
        dynamicReserveConfig.collateralFactor = collateralFactor;
    183
        targetSpoke.updateDynamicReserveConfig(reserveId, dynamicConfigKey, dynamicReserveConfig);
    184
      }
    185
    186
      /// @inheritdoc ISpokeConfigurator
    187
      function addMaxLiquidationBonus(
    188
        address spoke,
    189
        uint256 reserveId,
    190
        uint256 maxLiquidationBonus
    191
      ) external onlyOwner returns (uint24) {
    192
        ISpoke targetSpoke = ISpoke(spoke);
    193
        ISpoke.DynamicReserveConfig memory dynamicReserveConfig = targetSpoke.getDynamicReserveConfig(
    194
          reserveId,
    195
          _getReserveLastDynamicConfigKey(spoke, reserveId)
    196
        );
    197
        dynamicReserveConfig.maxLiquidationBonus = maxLiquidationBonus.toUint32();
    198
        return targetSpoke.addDynamicReserveConfig(reserveId, dynamicReserveConfig);
    199
      }
    200
    201
      /// @inheritdoc ISpokeConfigurator
    202
      function updateMaxLiquidationBonus(
    203
        address spoke,
    204
        uint256 reserveId,
    205
        uint24 dynamicConfigKey,
    206
        uint256 maxLiquidationBonus
    207
      ) external onlyOwner {
    208
        ISpoke targetSpoke = ISpoke(spoke);
    209
        ISpoke.DynamicReserveConfig memory dynamicReserveConfig = targetSpoke.getDynamicReserveConfig(
    210
          reserveId,
    211
          dynamicConfigKey
    212
        );
    213
        dynamicReserveConfig.maxLiquidationBonus = maxLiquidationBonus.toUint32();
    214
        targetSpoke.updateDynamicReserveConfig(reserveId, dynamicConfigKey, dynamicReserveConfig);
    215
      }
    216
    217
      /// @inheritdoc ISpokeConfigurator
    218
      function addLiquidationFee(
    219
        address spoke,
    220
        uint256 reserveId,
    221
        uint256 liquidationFee
    222
      ) external onlyOwner returns (uint24) {
    223
        ISpoke targetSpoke = ISpoke(spoke);
    224
        ISpoke.DynamicReserveConfig memory dynamicReserveConfig = targetSpoke.getDynamicReserveConfig(
    225
          reserveId,
    226
          _getReserveLastDynamicConfigKey(spoke, reserveId)
    227
        );
    228
        dynamicReserveConfig.liquidationFee = liquidationFee.toUint16();
    229
        return targetSpoke.addDynamicReserveConfig(reserveId, dynamicReserveConfig);
    230
      }
    231
    232
      /// @inheritdoc ISpokeConfigurator
    233
      function updateLiquidationFee(
    234
        address spoke,
    235
        uint256 reserveId,
    236
        uint24 dynamicConfigKey,
    237
        uint256 liquidationFee
    238
      ) external onlyOwner {
    239
        ISpoke targetSpoke = ISpoke(spoke);
    240
        ISpoke.DynamicReserveConfig memory dynamicReserveConfig = targetSpoke.getDynamicReserveConfig(
    241
          reserveId,
    242
          dynamicConfigKey
    243
        );
    244
        dynamicReserveConfig.liquidationFee = liquidationFee.toUint16();
    245
        targetSpoke.updateDynamicReserveConfig(reserveId, dynamicConfigKey, dynamicReserveConfig);
    246
      }
    247
    248
      /// @inheritdoc ISpokeConfigurator
    249
      function addDynamicReserveConfig(
    250
        address spoke,
    251
        uint256 reserveId,
    252
        ISpoke.DynamicReserveConfig calldata dynamicConfig
    253
      ) external onlyOwner returns (uint24) {
    254
        return ISpoke(spoke).addDynamicReserveConfig(reserveId, dynamicConfig);
    255
      }
    256
    257
      /// @inheritdoc ISpokeConfigurator
    258
      function updateDynamicReserveConfig(
    259
        address spoke,
    260
        uint256 reserveId,
    261
        uint24 dynamicConfigKey,
    262
        ISpoke.DynamicReserveConfig calldata dynamicConfig
    263
      ) external onlyOwner {
    264
        ISpoke(spoke).updateDynamicReserveConfig(reserveId, dynamicConfigKey, dynamicConfig);
    265
      }
    266
    267
      /// @inheritdoc ISpokeConfigurator
    268
      function pauseAllReserves(address spoke) external onlyOwner {
    269
        ISpoke targetSpoke = ISpoke(spoke);
    270
        uint256 reserveCount = targetSpoke.getReserveCount();
    271
        for (uint256 reserveId = 0; reserveId < reserveCount; ++reserveId) {
    272
          ISpoke.ReserveConfig memory reserveConfig = targetSpoke.getReserveConfig(reserveId);
    273
          reserveConfig.paused = true;
    274
          targetSpoke.updateReserveConfig(reserveId, reserveConfig);
    275
        }
    276
      }
    277
    278
      /// @inheritdoc ISpokeConfigurator
    279
      function freezeAllReserves(address spoke) external onlyOwner {
    280
        ISpoke targetSpoke = ISpoke(spoke);
    281
        uint256 reserveCount = targetSpoke.getReserveCount();
    282
        for (uint256 reserveId = 0; reserveId < reserveCount; ++reserveId) {
    283
          ISpoke.ReserveConfig memory reserveConfig = targetSpoke.getReserveConfig(reserveId);
    284
          reserveConfig.frozen = true;
    285
          targetSpoke.updateReserveConfig(reserveId, reserveConfig);
    286
        }
    287
      }
    288
    289
      /// @inheritdoc ISpokeConfigurator
    290
      function updatePositionManager(
    291
        address spoke,
    292
        address positionManager,
    293
        bool active
    294
      ) external onlyOwner {
    295
        ISpoke(spoke).updatePositionManager(positionManager, active);
    296
      }
    297
    298
      /// @inheritdoc ISpokeConfigurator
    299
      function getMaxReserves(address spoke) external view returns (uint256) {
    300
        return _maxReserves[spoke];
    301
      }
    302
    303
      /// @dev Returns the last dynamic config key of the reserve for the specified Spoke.
    304
      function _getReserveLastDynamicConfigKey(
    305
        address spoke,
    306
        uint256 reserveId
    307
      ) internal view returns (uint24) {
    308
        return ISpoke(spoke).getReserve(reserveId).dynamicConfigKey;
    309
      }
    310
    }
    311
    12.0% src/spoke/TreasurySpoke.sol
    Lines covered: 4 / 32 (12.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity 0.8.28;
    4
    5
    import {Ownable2Step, Ownable} from 'src/dependencies/openzeppelin/Ownable2Step.sol';
    6
    import {SafeERC20, IERC20} from 'src/dependencies/openzeppelin/SafeERC20.sol';
    7
    import {MathUtils} from 'src/libraries/math/MathUtils.sol';
    8
    import {IHubBase} from 'src/hub/interfaces/IHubBase.sol';
    9
    import {ITreasurySpoke, ISpokeBase} from 'src/spoke/interfaces/ITreasurySpoke.sol';
    10
    11
    /// @title TreasurySpoke
    12
    /// @author Aave Labs
    13
    /// @notice Spoke contract used as a treasury where accumulated fees are treated as supplied assets.
    14
    /// @dev Dedicated to a single user, controlled exclusively by the owner.
    15
    /// @dev Utilizes all assets from the Hub without restrictions, making reserve and asset identifiers aligned.
    16
    /// @dev Allows withdraw to claim fees and supply to invest back into the Hub via this dedicated spoke.
    17
    contract TreasurySpoke is ITreasurySpoke, Ownable2Step {
    18
      using SafeERC20 for IERC20;
    19
    20
      /// @inheritdoc ITreasurySpoke
    21
      IHubBase public immutable HUB;
    22
    23
      /// @dev Constructor.
    24
      /// @param owner_ The address of the owner.
    25
      /// @param hub_ The address of the Hub.
    26
      constructor(address owner_, address hub_) Ownable(owner_) {
    27
        require(hub_ != address(0), InvalidAddress());
    28
    29
        HUB = IHubBase(hub_);
    30
      }
    31
    32
      /// @inheritdoc ITreasurySpoke
    33
      function supply(
    34
        uint256 reserveId,
    35
        uint256 amount,
    36
        address
    37
      ) external onlyOwner returns (uint256, uint256) {
    38
        (address underlying, ) = HUB.getAssetUnderlyingAndDecimals(reserveId);
    39
        IERC20(underlying).safeTransferFrom(msg.sender, address(HUB), amount);
    40
        uint256 shares = HUB.add(reserveId, amount);
    41
    42
        return (shares, amount);
    43
      }
    44
    45
      /// @inheritdoc ITreasurySpoke
    46
      function withdraw(
    47
        uint256 reserveId,
    48
        uint256 amount,
    49
        address
    50
      ) external onlyOwner returns (uint256, uint256) {
    51
        // if amount to withdraw is greater than total supplied, withdraw all supplied assets
    52
        uint256 withdrawnAmount = MathUtils.min(
    53
          amount,
    54
          HUB.getSpokeAddedAssets(reserveId, address(this))
    55
        );
    56
        uint256 withdrawnShares = HUB.remove(reserveId, withdrawnAmount, msg.sender);
    57
    58
        return (withdrawnShares, withdrawnAmount);
    59
      }
    60
    61
      /// @inheritdoc ITreasurySpoke
    62
      function transfer(address token, address to, uint256 amount) external onlyOwner {
    63
        IERC20(token).safeTransfer(to, amount);
    64
      }
    65
    66
      /// @inheritdoc ITreasurySpoke
    67
      function getSuppliedAmount(uint256 reserveId) external view returns (uint256) {
    68
        return HUB.getSpokeAddedAssets(reserveId, address(this));
    69
      }
    70
    71
      /// @inheritdoc ITreasurySpoke
    72
      function getSuppliedShares(uint256 reserveId) external view returns (uint256) {
    73
        return HUB.getSpokeAddedShares(reserveId, address(this));
    74
      }
    75
    76
      /// @inheritdoc ISpokeBase
    77
      function borrow(uint256, uint256, address) external pure returns (uint256, uint256) {
    78
        revert UnsupportedAction();
    79
      }
    80
    81
      /// @inheritdoc ISpokeBase
    82
      function repay(uint256, uint256, address) external pure returns (uint256, uint256) {
    83
        revert UnsupportedAction();
    84
      }
    85
    86
      /// @inheritdoc ISpokeBase
    87
      function liquidationCall(uint256, uint256, address, uint256, bool) external pure {
    88
        revert UnsupportedAction();
    89
      }
    90
    91
      /// @inheritdoc ISpokeBase
    92
      function getUserDebt(uint256, address) external pure returns (uint256, uint256) {}
    93
    94
      /// @inheritdoc ISpokeBase
    95
      function getUserTotalDebt(uint256, address) external pure returns (uint256) {}
    96
    97
      /// @inheritdoc ISpokeBase
    98
      function getUserPremiumDebtRay(uint256, address) external pure returns (uint256) {}
    99
    100
      /// @inheritdoc ISpokeBase
    101
      function getReserveSuppliedAssets(uint256 reserveId) external view returns (uint256) {
    102
        return HUB.getSpokeAddedAssets(reserveId, address(this));
    103
      }
    104
    105
      /// @inheritdoc ISpokeBase
    106
      function getReserveSuppliedShares(uint256 reserveId) external view returns (uint256) {
    107
        return HUB.getSpokeAddedShares(reserveId, address(this));
    108
      }
    109
    110
      /// @inheritdoc ISpokeBase
    111
      function getUserSuppliedAssets(uint256, address) external pure returns (uint256) {}
    112
    113
      /// @inheritdoc ISpokeBase
    114
      function getUserSuppliedShares(uint256, address) external pure returns (uint256) {}
    115
    116
      /// @inheritdoc ISpokeBase
    117
      function getReserveDebt(uint256) external pure returns (uint256, uint256) {}
    118
    119
      /// @inheritdoc ISpokeBase
    120
      function getReserveTotalDebt(uint256) external pure returns (uint256) {}
    121
    }
    122
    100.0% src/spoke/instances/SpokeInstance.sol
    Lines covered: 10 / 10 (100.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity 0.8.28;
    4
    5
    import {LiquidationLogic} from 'src/spoke/libraries/LiquidationLogic.sol';
    6
    import {Spoke} from 'src/spoke/Spoke.sol';
    7
    8
    /// @title SpokeInstance
    9
    /// @author Aave Labs
    10
    /// @notice Implementation contract for the Spoke.
    11
    contract SpokeInstance is Spoke {
    12
      uint64 public constant SPOKE_REVISION = 1;
    13
    14
      /// @dev Constructor.
    15
      /// @dev During upgrade, must ensure that the new oracle is supporting existing assets on the spoke and the replaced oracle.
    16
      /// @param oracle_ The address of the oracle.
    17
      constructor(address oracle_) Spoke(oracle_) {
    18
        // @audit FIXME: Remove _disableInitializers to fix echidna coverage https://github.com/crytic/echidna/issues/1116#issuecomment-3596746122
    19
        // _disableInitializers();
    20
      }
    21
    22
      /// @notice Initializer.
    23
      /// @dev The authority contract must implement the `AccessManaged` interface for access control.
    24
      /// @param authority The address of the authority contract which manages permissions.
    25
      function initialize(address authority) external override reinitializer(SPOKE_REVISION) {
    26
        emit UpdateOracle(ORACLE);
    27
        require(authority != address(0), InvalidAddress());
    28
        __AccessManaged_init(authority);
    29
        if (_liquidationConfig.targetHealthFactor == 0) {
    30
          _liquidationConfig.targetHealthFactor = HEALTH_FACTOR_LIQUIDATION_THRESHOLD;
    31
          emit UpdateLiquidationConfig(_liquidationConfig);
    32
        }
    33
      }
    34
    }
    35
    0.0% src/spoke/interfaces/IAaveOracle.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    import {IPriceOracle} from 'src/spoke/interfaces/IPriceOracle.sol';
    6
    7
    /// @title IAaveOracle
    8
    /// @author Aave Labs
    9
    /// @notice Interface for the Aave Oracle.
    10
    interface IAaveOracle is IPriceOracle {
    11
      /// @dev Emitted when the price feed source of a reserve is updated.
    12
      /// @param reserveId The identifier of the reserve.
    13
      /// @param source The price feed source of the reserve.
    14
      event UpdateReserveSource(uint256 indexed reserveId, address indexed source);
    15
    16
      /// @dev Thrown when the price feed source uses a different number of decimals than the oracle.
    17
      /// @param reserveId The identifier of the reserve.
    18
      error InvalidSourceDecimals(uint256 reserveId);
    19
    20
      /// @dev Thrown when the price feed source is invalid (zero address).
    21
      /// @param reserveId The identifier of the reserve.
    22
      error InvalidSource(uint256 reserveId);
    23
    24
      /// @dev Thrown when the price feed source returns an invalid price (non-positive).
    25
      /// @param reserveId The identifier of the reserve.
    26
      error InvalidPrice(uint256 reserveId);
    27
    28
      /// @dev Thrown when the given address is invalid.
    29
      error InvalidAddress();
    30
    31
      /// @notice Sets the price feed source of a reserve.
    32
      /// @dev Must be called by the spoke.
    33
      /// @dev The source must implement the AggregatorV3Interface.
    34
      /// @param reserveId The identifier of the reserve.
    35
      /// @param source The price feed source of the reserve.
    36
      function setReserveSource(uint256 reserveId, address source) external;
    37
    38
      /// @notice Returns the prices of multiple reserves.
    39
      /// @param reserveIds The identifiers of the reserves.
    40
      /// @return prices The prices of the reserves.
    41
      function getReservesPrices(
    42
        uint256[] calldata reserveIds
    43
      ) external view returns (uint256[] memory);
    44
    45
      /// @notice Returns the price feed source of a reserve.
    46
      /// @param reserveId The identifier of the reserve.
    47
      /// @return source The price feed source of the reserve.
    48
      function getReserveSource(uint256 reserveId) external view returns (address);
    49
    50
      /// @notice Returns the description of the oracle.
    51
      /// @return The description of the oracle.
    52
      function DESCRIPTION() external view returns (string memory);
    53
    }
    54
    0.0% src/spoke/interfaces/IPriceOracle.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    /// @title IPriceOracle
    6
    /// @author Aave Labs
    7
    /// @notice Basic interface for any price oracle.
    8
    /// @dev All prices must use the same number of decimals as the oracle and should be returned in the same currency.
    9
    interface IPriceOracle {
    10
      /// @dev Reverts if the caller is not the spoke.
    11
      error OnlySpoke();
    12
    13
      /// @notice Returns the address of the spoke.
    14
      /// @return The address of the spoke.
    15
      function SPOKE() external view returns (address);
    16
    17
      /// @notice Returns the number of decimals used to return prices.
    18
      /// @return The number of decimals.
    19
      function DECIMALS() external view returns (uint8);
    20
    21
      /// @notice Returns the reserve price with `decimals` precision.
    22
      /// @param reserveId The identifier of the reserve.
    23
      /// @return The price of the reserve.
    24
      function getReservePrice(uint256 reserveId) external view returns (uint256);
    25
    }
    26
    0.0% src/spoke/interfaces/ISpoke.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    import {IAccessManaged} from 'src/dependencies/openzeppelin/IAccessManaged.sol';
    6
    import {INoncesKeyed} from 'src/interfaces/INoncesKeyed.sol';
    7
    import {IMulticall} from 'src/interfaces/IMulticall.sol';
    8
    import {IHubBase} from 'src/hub/interfaces/IHubBase.sol';
    9
    import {ISpokeBase} from 'src/spoke/interfaces/ISpokeBase.sol';
    10
    11
    type ReserveFlags is uint8;
    12
    13
    /// @title ISpoke
    14
    /// @author Aave Labs
    15
    /// @notice Full interface for Spoke.
    16
    interface ISpoke is ISpokeBase, IMulticall, INoncesKeyed, IAccessManaged {
    17
      /// @notice Reserve level data.
    18
      /// @dev underlying The address of the underlying asset.
    19
      /// @dev hub The address of the associated Hub.
    20
      /// @dev assetId The identifier of the asset in the Hub.
    21
      /// @dev decimals The number of decimals of the underlying asset.
    22
      /// @dev dynamicConfigKey The key of the last reserve dynamic config.
    23
      /// @dev collateralRisk The risk associated with a collateral asset, expressed in BPS.
    24
      /// @dev flags The packed boolean flags of the reserve (a wrapped uint8).
    25
      struct Reserve {
    26
        address underlying;
    27
        //
    28
        IHubBase hub;
    29
        uint16 assetId;
    30
        uint8 decimals;
    31
        uint24 dynamicConfigKey;
    32
        uint24 collateralRisk;
    33
        ReserveFlags flags;
    34
      }
    35
    36
      /// @notice Reserve configuration. Subset of the `Reserve` struct.
    37
      /// @dev collateralRisk The risk associated with a collateral asset, expressed in BPS.
    38
      /// @dev paused True if all actions are prevented for the reserve.
    39
      /// @dev frozen True if new activity is prevented for the reserve.
    40
      /// @dev borrowable True if the reserve is borrowable.
    41
      /// @dev liquidatable True if the reserve can be liquidated when used as collateral.
    42
      /// @dev receiveSharesEnabled True if the liquidator can receive collateral shares during liquidation.
    43
      struct ReserveConfig {
    44
        uint24 collateralRisk;
    45
        bool paused;
    46
        bool frozen;
    47
        bool borrowable;
    48
        bool liquidatable;
    49
        bool receiveSharesEnabled;
    50
      }
    51
    52
      /// @notice Dynamic reserve configuration data.
    53
      /// @dev collateralFactor The proportion of a reserve's value eligible to be used as collateral, expressed in BPS.
    54
      /// @dev maxLiquidationBonus The maximum extra amount of collateral given to the liquidator as bonus, expressed in BPS. 100_00 represents 0.00% bonus.
    55
      /// @dev liquidationFee The protocol fee charged on liquidations, taken from the collateral bonus given to the liquidator, expressed in BPS.
    56
      struct DynamicReserveConfig {
    57
        uint16 collateralFactor;
    58
        uint32 maxLiquidationBonus;
    59
        uint16 liquidationFee;
    60
      }
    61
    62
      /// @notice Liquidation configuration data.
    63
      /// @dev targetHealthFactor The ideal health factor to restore a user position during liquidation, expressed in WAD.
    64
      /// @dev healthFactorForMaxBonus The health factor under which liquidation bonus is maximum, expressed in WAD.
    65
      /// @dev liquidationBonusFactor The value multiplied by `maxLiquidationBonus` to compute the minimum liquidation bonus, expressed in BPS.
    66
      struct LiquidationConfig {
    67
        uint128 targetHealthFactor;
    68
        uint64 healthFactorForMaxBonus;
    69
        uint16 liquidationBonusFactor;
    70
      }
    71
    72
      /// @notice User position data per reserve.
    73
      /// @dev drawnShares The drawn shares of the user position.
    74
      /// @dev premiumShares The premium shares of the user position.
    75
      /// @dev premiumOffsetRay The premium offset of the user position, used to calculate the premium, expressed in asset units and scaled by RAY.
    76
      /// @dev suppliedShares The supplied shares of the user position.
    77
      /// @dev dynamicConfigKey The key of the user position dynamic config.
    78
      struct UserPosition {
    79
        uint120 drawnShares;
    80
        uint120 premiumShares;
    81
        //
    82
        int200 premiumOffsetRay;
    83
        //
    84
        uint120 suppliedShares;
    85
        uint24 dynamicConfigKey;
    86
      }
    87
    88
      /// @notice Position manager configuration data.
    89
      /// @dev approval The mapping of position manager user approvals.
    90
      /// @dev active True if the position manager is active.
    91
      struct PositionManagerConfig {
    92
        mapping(address user => bool) approval;
    93
        bool active;
    94
      }
    95
    96
      /// @notice User position status data.
    97
      /// @dev map The map of bitmap buckets for the position status.
    98
      /// @dev riskPremium The risk premium of the user position, expressed in BPS.
    99
      struct PositionStatus {
    100
        mapping(uint256 bucket => uint256) map;
    101
        uint24 riskPremium;
    102
      }
    103
    104
      /// @notice User account data describing a user position and its health.
    105
      /// @dev riskPremium The risk premium of the user position, expressed in BPS.
    106
      /// @dev avgCollateralFactor The weighted average collateral factor of the user position, expressed in WAD.
    107
      /// @dev healthFactor The health factor of the user position, expressed in WAD. 1e18 represents a health factor of 1.00.
    108
      /// @dev totalCollateralValue The total collateral value of the user position, expressed in units of base currency. 1e26 represents 1 USD.
    109
      /// @dev totalDebtValue The total debt value of the user position, expressed in units of base currency. 1e26 represents 1 USD.
    110
      /// @dev activeCollateralCount The number of active collaterals, which includes reserves with `collateralFactor` > 0, `enabledAsCollateral` and `suppliedAmount` > 0.
    111
      /// @dev borrowedCount The number of borrowed reserves of the user position.
    112
      struct UserAccountData {
    113
        uint256 riskPremium;
    114
        uint256 avgCollateralFactor;
    115
        uint256 healthFactor;
    116
        uint256 totalCollateralValue;
    117
        uint256 totalDebtValue;
    118
        uint256 activeCollateralCount;
    119
        uint256 borrowedCount;
    120
      }
    121
    122
      /// @notice Emitted when the oracle address of the spoke is updated.
    123
      /// @param oracle The new address of the oracle.
    124
      event UpdateOracle(address indexed oracle);
    125
    126
      /// @notice Emitted when a liquidation config is updated.
    127
      /// @param config The new liquidation config.
    128
      event UpdateLiquidationConfig(LiquidationConfig config);
    129
    130
      /// @notice Emitted when a reserve is added.
    131
      /// @param reserveId The identifier of the reserve.
    132
      /// @param assetId The identifier of the asset.
    133
      /// @param hub The address of the Hub where the asset is listed.
    134
      event AddReserve(uint256 indexed reserveId, uint256 indexed assetId, address indexed hub);
    135
    136
      /// @notice Emitted when a reserve configuration is updated.
    137
      /// @param reserveId The identifier of the reserve.
    138
      /// @param config The reserve configuration.
    139
      event UpdateReserveConfig(uint256 indexed reserveId, ReserveConfig config);
    140
    141
      /// @notice Emitted when the price source of a reserve is updated.
    142
      /// @param reserveId The identifier of the reserve.
    143
      /// @param priceSource The address of the new price source.
    144
      event UpdateReservePriceSource(uint256 indexed reserveId, address indexed priceSource);
    145
    146
      /// @notice Emitted when a dynamic reserve config is added.
    147
      /// @dev The config key is the next available key for the reserve, which is now the latest config
    148
      /// key of the reserve.
    149
      /// @param reserveId The identifier of the reserve.
    150
      /// @param dynamicConfigKey The key of the added dynamic config.
    151
      /// @param config The dynamic reserve config.
    152
      event AddDynamicReserveConfig(
    153
        uint256 indexed reserveId,
    154
        uint24 indexed dynamicConfigKey,
    155
        DynamicReserveConfig config
    156
      );
    157
    158
      /// @notice Emitted when a dynamic reserve config is updated.
    159
      /// @param reserveId The identifier of the reserve.
    160
      /// @param dynamicConfigKey The key of the updated dynamic config.
    161
      /// @param config The dynamic reserve config.
    162
      event UpdateDynamicReserveConfig(
    163
        uint256 indexed reserveId,
    164
        uint24 indexed dynamicConfigKey,
    165
        DynamicReserveConfig config
    166
      );
    167
    168
      /// @notice Emitted on updatePositionManager action.
    169
      /// @param positionManager The address of the position manager.
    170
      /// @param active True if position manager has become active.
    171
      event UpdatePositionManager(address indexed positionManager, bool active);
    172
    173
      /// @notice Emitted on setUsingAsCollateral action.
    174
      /// @param reserveId The reserve identifier of the underlying asset.
    175
      /// @param caller The transaction initiator.
    176
      /// @param user The owner of the position being modified.
    177
      /// @param usingAsCollateral Whether the reserve is enabled or disabled as collateral.
    178
      event SetUsingAsCollateral(
    179
        uint256 indexed reserveId,
    180
        address indexed caller,
    181
        address indexed user,
    182
        bool usingAsCollateral
    183
      );
    184
    185
      /// @notice Emitted when a user's dynamic config is refreshed for all reserves to their latest config key.
    186
      /// @param user The address of the user.
    187
      event RefreshAllUserDynamicConfig(address indexed user);
    188
    189
      /// @notice Emitted when a user's dynamic config is refreshed for a single reserve to its latest config key.
    190
      /// @param user The address of the user.
    191
      /// @param reserveId The identifier of the reserve.
    192
      event RefreshSingleUserDynamicConfig(address indexed user, uint256 reserveId);
    193
    194
      /// @notice Emitted on updateUserRiskPremium action.
    195
      /// @param user The owner of the position being modified.
    196
      /// @param riskPremium The new risk premium (BPS) value of user.
    197
      event UpdateUserRiskPremium(address indexed user, uint256 riskPremium);
    198
    199
      /// @notice Emitted on setUserPositionManager or renouncePositionManagerRole action.
    200
      /// @param user The address of the user on whose behalf position manager can act.
    201
      /// @param positionManager The address of the position manager.
    202
      /// @param approve True if position manager approval was granted, false if it was revoked.
    203
      event SetUserPositionManager(address indexed user, address indexed positionManager, bool approve);
    204
    205
      /// @notice Emitted on refreshPremiumDebt action.
    206
      /// @param reserveId The identifier of the reserve.
    207
      /// @param user The address of the user.
    208
      /// @param premiumDelta The change in premium values.
    209
      event RefreshPremiumDebt(
    210
        uint256 indexed reserveId,
    211
        address indexed user,
    212
        IHubBase.PremiumDelta premiumDelta
    213
      );
    214
    215
      /// @notice Emitted on liquidations that report deficit to the Hub.
    216
      /// @param reserveId The identifier of the reserve.
    217
      /// @param user The address of the user.
    218
      /// @param drawnShares The amount of drawn shares reported as deficit.
    219
      /// @param premiumDelta The premium delta data struct reported as deficit.
    220
      event ReportDeficit(
    221
        uint256 indexed reserveId,
    222
        address indexed user,
    223
        uint256 drawnShares,
    224
        IHubBase.PremiumDelta premiumDelta
    225
      );
    226
    227
      /// @notice Thrown when an asset is not listed on the Hub when adding a reserve.
    228
      error AssetNotListed();
    229
    230
      /// @notice Thrown when adding a new reserve if that reserve already exists for a given Hub/assetId pair.
    231
      error ReserveExists();
    232
    233
      /// @notice Thrown when adding a new reserve if an asset id is invalid.
    234
      error InvalidAssetId();
    235
    236
      /// @notice Thrown when updating a reserve if it is not listed.
    237
      error ReserveNotListed();
    238
    239
      /// @notice Thrown when a reserve is not borrowable during a `borrow` action.
    240
      error ReserveNotBorrowable();
    241
    242
      /// @notice Thrown when a reserve is paused during an attempted action.
    243
      error ReservePaused();
    244
    245
      /// @notice Thrown when a reserve is frozen.
    246
      /// @dev Can only occur during an attempted `supply`, `borrow`, or `setUsingAsCollateral` action.
    247
      error ReserveFrozen();
    248
    249
      /// @notice Thrown when the collateral reserve is not enabled to be liquidated.
    250
      error CollateralCannotBeLiquidated();
    251
    252
      /// @notice Thrown when an action causes a user's health factor to fall below the liquidation threshold.
    253
      error HealthFactorBelowThreshold();
    254
    255
      /// @notice Thrown when reserve is not enabled as collateral during liquidation.
    256
      error ReserveNotEnabledAsCollateral();
    257
    258
      /// @notice Thrown when a specified reserve is not supplied by the user during liquidation.
    259
      error ReserveNotSupplied();
    260
    261
      /// @notice Thrown when a specified reserve is not borrowed by the user during liquidation.
    262
      error ReserveNotBorrowed();
    263
    264
      /// @notice Thrown when an unauthorized caller attempts an action.
    265
      error Unauthorized();
    266
    267
      /// @notice Thrown if a config key is uninitialized when updating a dynamic reserve config.
    268
      error ConfigKeyUninitialized();
    269
    270
      /// @notice Thrown if an inactive position manager is set as a user's position manager.
    271
      error InactivePositionManager();
    272
    273
      /// @notice Thrown when a signature is invalid.
    274
      error InvalidSignature();
    275
    276
      /// @notice Thrown for an invalid zero address.
    277
      error InvalidAddress();
    278
    279
      /// @notice Thrown when the oracle decimals are not 8 in the constructor.
    280
      error InvalidOracleDecimals();
    281
    282
      /// @notice Thrown when a collateral risk exceeds the maximum allowed.
    283
      error InvalidCollateralRisk();
    284
    285
      /// @notice Thrown if a liquidation config is invalid when it is updated.
    286
      error InvalidLiquidationConfig();
    287
    288
      /// @notice Thrown when a liquidation fee is invalid.
    289
      error InvalidLiquidationFee();
    290
    291
      /// @notice Thrown when a collateral factor and max liquidation bonus are invalid.
    292
      error InvalidCollateralFactorAndMaxLiquidationBonus();
    293
    294
      /// @notice Thrown when trying to set zero collateralFactor on historic dynamic configuration keys.
    295
      error InvalidCollateralFactor();
    296
    297
      /// @notice Thrown when a self-liquidation is attempted.
    298
      error SelfLiquidation();
    299
    300
      /// @notice Thrown during liquidation when a user's health factor is not below the liquidation threshold.
    301
      error HealthFactorNotBelowThreshold();
    302
    303
      /// @notice Thrown when collateral or debt dust remains after a liquidation, and neither reserve is fully liquidated.
    304
      error MustNotLeaveDust();
    305
    306
      /// @notice Thrown when a debt to cover input is zero.
    307
      error InvalidDebtToCover();
    308
    309
      /// @notice Thrown when the liquidator tries to receive shares for a collateral reserve that is frozen or is not enabled to receive shares.
    310
      error CannotReceiveShares();
    311
    312
      /// @notice Thrown when the maximum number of dynamic config keys is reached.
    313
      error MaximumDynamicConfigKeyReached();
    314
    315
      /// @notice Updates the liquidation config.
    316
      /// @param config The liquidation config.
    317
      function updateLiquidationConfig(LiquidationConfig calldata config) external;
    318
    319
      /// @notice Adds a new reserve to the spoke.
    320
      /// @dev Allowed even if the spoke has not yet been added to the Hub.
    321
      /// @dev Allowed even if the `active` flag is `false`.
    322
      /// @dev Allowed even if the spoke has been added but the `addCap` is zero.
    323
      /// @param hub The address of the Hub where the asset is listed.
    324
      /// @param assetId The identifier of the asset in the Hub.
    325
      /// @param priceSource The address of the price source for the asset.
    326
      /// @param config The initial reserve configuration.
    327
      /// @param dynamicConfig The initial dynamic reserve configuration.
    328
      /// @return The identifier of the newly added reserve.
    329
      function addReserve(
    330
        address hub,
    331
        uint256 assetId,
    332
        address priceSource,
    333
        ReserveConfig calldata config,
    334
        DynamicReserveConfig calldata dynamicConfig
    335
      ) external returns (uint256);
    336
    337
      /// @notice Updates the reserve config for a given reserve.
    338
      /// @dev It reverts if the reserve associated with the given reserve identifier is not listed.
    339
      /// @param reserveId The identifier of the reserve.
    340
      /// @param params The new reserve config.
    341
      function updateReserveConfig(uint256 reserveId, ReserveConfig calldata params) external;
    342
    343
      /// @notice Updates the price source of a reserve.
    344
      /// @param reserveId The identifier of the reserve.
    345
      /// @param priceSource The address of the price source.
    346
      function updateReservePriceSource(uint256 reserveId, address priceSource) external;
    347
    348
      /// @notice Updates the dynamic reserve config for a given reserve.
    349
      /// @dev It reverts if the reserve associated with the given reserve identifier is not listed.
    350
      /// @dev Appends dynamic config to the next available key; reverts if `MAX_ALLOWED_DYNAMIC_CONFIG_KEY` is reached.
    351
      /// @param reserveId The identifier of the reserve.
    352
      /// @param dynamicConfig The new dynamic reserve config.
    353
      /// @return dynamicConfigKey The key of the added dynamic config.
    354
      function addDynamicReserveConfig(
    355
        uint256 reserveId,
    356
        DynamicReserveConfig calldata dynamicConfig
    357
      ) external returns (uint24 dynamicConfigKey);
    358
    359
      /// @notice Updates the dynamic reserve config for a given reserve at the specified key.
    360
      /// @dev It reverts if the reserve associated with the given reserve identifier is not listed.
    361
      /// @dev Reverts with `ConfigKeyUninitialized` if the config key has not been initialized yet.
    362
      /// @dev Reverts with `InvalidCollateralFactor` if the collateral factor is 0.
    363
      /// @param reserveId The identifier of the reserve.
    364
      /// @param dynamicConfigKey The key of the config to update.
    365
      /// @param dynamicConfig The new dynamic reserve config.
    366
      function updateDynamicReserveConfig(
    367
        uint256 reserveId,
    368
        uint24 dynamicConfigKey,
    369
        DynamicReserveConfig calldata dynamicConfig
    370
      ) external;
    371
    372
      /// @notice Allows an approved caller (admin) to toggle the active status of position manager.
    373
      /// @param positionManager The address of the position manager.
    374
      /// @param active True if positionManager is to be set as active.
    375
      function updatePositionManager(address positionManager, bool active) external;
    376
    377
      /// @notice Allows suppliers to enable/disable a specific supplied reserve as collateral.
    378
      /// @dev It reverts if the reserve associated with the given reserve identifier is not listed.
    379
      /// @dev Caller must be `onBehalfOf` or an authorized position manager for `onBehalfOf`.
    380
      /// @param reserveId The reserve identifier of the underlying asset.
    381
      /// @param usingAsCollateral True if the user wants to use the supply as collateral.
    382
      /// @param onBehalfOf The owner of the position being modified.
    383
      function setUsingAsCollateral(
    384
        uint256 reserveId,
    385
        bool usingAsCollateral,
    386
        address onBehalfOf
    387
      ) external;
    388
    389
      /// @notice Allows updating the risk premium on onBehalfOf position.
    390
      /// @dev Caller must be `onBehalfOf`, an authorized position manager for `onBehalfOf`, or admin.
    391
      /// @param onBehalfOf The owner of the position being modified.
    392
      function updateUserRiskPremium(address onBehalfOf) external;
    393
    394
      /// @notice Allows updating the dynamic configuration for all collateral reserves on onBehalfOf position.
    395
      /// @dev Caller must be `onBehalfOf`, an authorized position manager for `onBehalfOf`, or admin.
    396
      /// @param onBehalfOf The owner of the position being modified.
    397
      function updateUserDynamicConfig(address onBehalfOf) external;
    398
    399
      /// @notice Enables a user to grant or revoke approval for a position manager
    400
      /// @param positionManager The address of the position manager.
    401
      /// @param approve True to approve the position manager, false to revoke approval.
    402
      function setUserPositionManager(address positionManager, bool approve) external;
    403
    404
      /// @notice Enables a user to grant or revoke approval for a position manager using an EIP712-typed intent.
    405
      /// @dev Uses keyed-nonces where for each key's namespace nonce is consumed sequentially.
    406
      /// @param positionManager The address of the position manager.
    407
      /// @param user The address of the user on whose behalf position manager can act.
    408
      /// @param approve True to approve the position manager, false to revoke approval.
    409
      /// @param nonce The key-prefixed nonce for the signature.
    410
      /// @param deadline The deadline for the signature.
    411
      /// @param signature The EIP712-compliant signature bytes.
    412
      function setUserPositionManagerWithSig(
    413
        address positionManager,
    414
        address user,
    415
        bool approve,
    416
        uint256 nonce,
    417
        uint256 deadline,
    418
        bytes calldata signature
    419
      ) external;
    420
    421
      /// @notice Allows position manager (as caller) to renounce their approval given by the user.
    422
      /// @param user The address of the user.
    423
      function renouncePositionManagerRole(address user) external;
    424
    425
      /// @notice Allows consuming a permit signature for the given reserve's underlying asset.
    426
      /// @dev It reverts if the reserve associated with the given reserve identifier is not listed.
    427
      /// @dev Spender is the corresponding Hub of the given reserve.
    428
      /// @param reserveId The identifier of the reserve.
    429
      /// @param onBehalfOf The address of the user on whose behalf the permit is being used.
    430
      /// @param value The amount of the underlying asset to permit.
    431
      /// @param deadline The deadline for the permit.
    432
      function permitReserve(
    433
        uint256 reserveId,
    434
        address onBehalfOf,
    435
        uint256 value,
    436
        uint256 deadline,
    437
        uint8 permitV,
    438
        bytes32 permitR,
    439
        bytes32 permitS
    440
      ) external;
    441
    442
      /// @notice Returns the liquidation config struct.
    443
      function getLiquidationConfig() external view returns (LiquidationConfig memory);
    444
    445
      /// @notice Returns the number of listed reserves on the spoke.
    446
      /// @dev Count includes reserves that are not currently active.
    447
      function getReserveCount() external view returns (uint256);
    448
    449
      /// @notice Returns the reserve struct data in storage.
    450
      /// @dev It reverts if the reserve associated with the given reserve identifier is not listed.
    451
      /// @param reserveId The identifier of the reserve.
    452
      /// @return The reserve struct.
    453
      function getReserve(uint256 reserveId) external view returns (Reserve memory);
    454
    455
      /// @notice Returns the reserve configuration struct data in storage.
    456
      /// @dev It reverts if the reserve associated with the given reserve identifier is not listed.
    457
      /// @param reserveId The identifier of the reserve.
    458
      /// @return The reserve configuration struct.
    459
      function getReserveConfig(uint256 reserveId) external view returns (ReserveConfig memory);
    460
    461
      /// @notice Returns the dynamic reserve configuration struct at the specified key.
    462
      /// @dev It reverts if the reserve associated with the given reserve identifier is not listed.
    463
      /// @dev Does not revert if `dynamicConfigKey` is unset.
    464
      /// @param reserveId The identifier of the reserve.
    465
      /// @param dynamicConfigKey The key of the dynamic config.
    466
      /// @return The dynamic reserve configuration struct.
    467
      function getDynamicReserveConfig(
    468
        uint256 reserveId,
    469
        uint24 dynamicConfigKey
    470
      ) external view returns (DynamicReserveConfig memory);
    471
    472
      /// @notice Returns two flags indicating whether the reserve is used as collateral and whether it is borrowed by the user.
    473
      /// @dev It reverts if the reserve associated with the given reserve identifier is not listed.
    474
      /// @dev Even if enabled as collateral, it will only count towards user position if the collateral factor is greater than 0.
    475
      /// @param reserveId The identifier of the reserve.
    476
      /// @param user The address of the user.
    477
      /// @return True if the reserve is enabled as collateral by the user.
    478
      /// @return True if the reserve is borrowed by the user.
    479
      function getUserReserveStatus(uint256 reserveId, address user) external view returns (bool, bool);
    480
    481
      /// @notice Returns the user position struct in storage.
    482
      /// @dev It reverts if the reserve associated with the given reserve identifier is not listed.
    483
      /// @param reserveId The identifier of the reserve.
    484
      /// @param user The address of the user.
    485
      /// @return The user position struct.
    486
      function getUserPosition(
    487
        uint256 reserveId,
    488
        address user
    489
      ) external view returns (UserPosition memory);
    490
    491
      /// @notice Returns the most up-to-date user account data information.
    492
      /// @dev Utilizes user's current dynamic configuration of user position.
    493
      /// @param user The address of the user.
    494
      /// @return The user account data struct.
    495
      function getUserAccountData(address user) external view returns (UserAccountData memory);
    496
    497
      /// @notice Returns the risk premium from the user's last position update.
    498
      /// @param user The address of the user.
    499
      /// @return The risk premium of the user from the last position update, expressed in BPS.
    500
      function getUserLastRiskPremium(address user) external view returns (uint256);
    501
    502
      /// @notice Returns the liquidation bonus for a given health factor, based on the user's current dynamic configuration.
    503
      /// @dev It reverts if the reserve associated with the given reserve identifier is not listed.
    504
      /// @param reserveId The identifier of the reserve.
    505
      /// @param user The address of the user.
    506
      /// @param healthFactor The health factor of the user.
    507
      function getLiquidationBonus(
    508
        uint256 reserveId,
    509
        address user,
    510
        uint256 healthFactor
    511
      ) external view returns (uint256);
    512
    513
      /// @notice Returns whether positionManager is currently activated by governance.
    514
      /// @param positionManager The address of the position manager.
    515
      /// @return True if positionManager is currently active.
    516
      function isPositionManagerActive(address positionManager) external view returns (bool);
    517
    518
      /// @notice Returns whether positionManager is active and approved by user.
    519
      /// @param user The address of the user.
    520
      /// @param positionManager The address of the position manager.
    521
      /// @return True if positionManager is active and approved by user.
    522
      function isPositionManager(address user, address positionManager) external view returns (bool);
    523
    524
      /// @notice Returns the EIP-712 domain separator.
    525
      function DOMAIN_SEPARATOR() external view returns (bytes32);
    526
    527
      /// @notice Returns the address of the external `LiquidationLogic` library.
    528
      /// @return The address of the library.
    529
      function getLiquidationLogic() external pure returns (address);
    530
    531
      /// @notice Returns the type hash for the SetUserPositionManager intent.
    532
      /// @return The bytes-encoded EIP-712 struct hash representing the intent.
    533
      function SET_USER_POSITION_MANAGER_TYPEHASH() external view returns (bytes32);
    534
    535
      /// @notice Returns the address of the AaveOracle contract.
    536
      function ORACLE() external view returns (address);
    537
    }
    538
    0.0% src/spoke/interfaces/ISpokeBase.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    import {IHubBase} from 'src/hub/interfaces/IHubBase.sol';
    6
    7
    /// @title ISpokeBase
    8
    /// @author Aave Labs
    9
    /// @notice Minimal interface for Spoke.
    10
    interface ISpokeBase {
    11
      /// @notice Emitted on the supply action.
    12
      /// @param reserveId The reserve identifier of the underlying asset.
    13
      /// @param caller The transaction initiator, and supplier of the underlying asset.
    14
      /// @param user The owner of the modified position.
    15
      /// @param suppliedShares The amount of supply shares minted.
    16
      /// @param suppliedAmount The amount of underlying asset supplied.
    17
      event Supply(
    18
        uint256 indexed reserveId,
    19
        address indexed caller,
    20
        address indexed user,
    21
        uint256 suppliedShares,
    22
        uint256 suppliedAmount
    23
      );
    24
    25
      /// @notice Emitted on the withdraw action.
    26
      /// @param reserveId The reserve identifier of the underlying asset.
    27
      /// @param caller The transaction initiator, and recipient of the underlying asset being withdrawn.
    28
      /// @param user The owner of the modified position.
    29
      /// @param withdrawnShares The amount of supply shares burned.
    30
      /// @param withdrawnAmount The amount of underlying asset withdrawn.
    31
      event Withdraw(
    32
        uint256 indexed reserveId,
    33
        address indexed caller,
    34
        address indexed user,
    35
        uint256 withdrawnShares,
    36
        uint256 withdrawnAmount
    37
      );
    38
    39
      /// @notice Emitted on the borrow action.
    40
      /// @param reserveId The reserve identifier of the underlying asset.
    41
      /// @param caller The transaction initiator, and recipient of the underlying asset being borrowed.
    42
      /// @param user The owner of the position on which debt is generated.
    43
      /// @param drawnShares The amount of debt shares minted.
    44
      /// @param drawnAmount The amount of underlying asset borrowed.
    45
      event Borrow(
    46
        uint256 indexed reserveId,
    47
        address indexed caller,
    48
        address indexed user,
    49
        uint256 drawnShares,
    50
        uint256 drawnAmount
    51
      );
    52
    53
      /// @notice Emitted on the repay action.
    54
      /// @param reserveId The reserve identifier of the underlying asset.
    55
      /// @param caller The transaction initiator who is repaying the underlying asset.
    56
      /// @param user The owner of the position whose debt is being repaid.
    57
      /// @param drawnShares The amount of drawn shares burned.
    58
      /// @param totalAmountRepaid The amount of drawn and premium underlying assets repaid.
    59
      /// @param premiumDelta A struct representing the changes to premium debt after repayment.
    60
      event Repay(
    61
        uint256 indexed reserveId,
    62
        address indexed caller,
    63
        address indexed user,
    64
        uint256 drawnShares,
    65
        uint256 totalAmountRepaid,
    66
        IHubBase.PremiumDelta premiumDelta
    67
      );
    68
    69
      /// @dev Emitted when a borrower is liquidated.
    70
      /// @param collateralReserveId The identifier of the reserve used as collateral, to receive as a result of the liquidation.
    71
      /// @param debtReserveId The identifier of the reserve to be repaid with the liquidation.
    72
      /// @param user The address of the borrower getting liquidated.
    73
      /// @param liquidator The address of the liquidator.
    74
      /// @param receiveShares True if the liquidator received collateral in supplied shares rather than underlying assets.
    75
      /// @param debtToLiquidate The debt amount of borrowed reserve to be liquidated.
    76
      /// @param drawnSharesToLiquidate The amount of drawn shares to be liquidated.
    77
      /// @param premiumDelta A struct representing the changes to premium debt after liquidation.
    78
      /// @param collateralToLiquidate The total amount of collateral asset to be liquidated, inclusive of liquidation fee.
    79
      /// @param collateralSharesToLiquidate The total amount of collateral shares to liquidate.
    80
      /// @param collateralSharesToLiquidator The amount of collateral shares that the liquidator received.
    81
      event LiquidationCall(
    82
        uint256 indexed collateralReserveId,
    83
        uint256 indexed debtReserveId,
    84
        address indexed user,
    85
        address liquidator,
    86
        bool receiveShares,
    87
        uint256 debtToLiquidate,
    88
        uint256 drawnSharesToLiquidate,
    89
        IHubBase.PremiumDelta premiumDelta,
    90
        uint256 collateralToLiquidate,
    91
        uint256 collateralSharesToLiquidate,
    92
        uint256 collateralSharesToLiquidator
    93
      );
    94
    95
      /// @notice Supplies an amount of underlying asset of the specified reserve.
    96
      /// @dev It reverts if the reserve associated with the given reserve identifier is not listed.
    97
      /// @dev The Spoke pulls the underlying asset from the caller, so prior token approval is required.
    98
      /// @dev Caller must be `onBehalfOf` or an authorized position manager for `onBehalfOf`.
    99
      /// @param reserveId The reserve identifier.
    100
      /// @param amount The amount of asset to supply.
    101
      /// @param onBehalfOf The owner of the position to add supply shares to.
    102
      /// @return The amount of shares supplied.
    103
      /// @return The amount of assets supplied.
    104
      function supply(
    105
        uint256 reserveId,
    106
        uint256 amount,
    107
        address onBehalfOf
    108
      ) external returns (uint256, uint256);
    109
    110
      /// @notice Withdraws a specified amount of underlying asset from the given reserve.
    111
      /// @dev It reverts if the reserve associated with the given reserve identifier is not listed.
    112
      /// @dev Providing an amount greater than the maximum withdrawable value signals a full withdrawal.
    113
      /// @dev Caller must be `onBehalfOf` or an authorized position manager for `onBehalfOf`.
    114
      /// @dev Caller receives the underlying asset withdrawn.
    115
      /// @param reserveId The identifier of the reserve.
    116
      /// @param amount The amount of asset to withdraw.
    117
      /// @param onBehalfOf The owner of position to remove supply shares from.
    118
      /// @return The amount of shares withdrawn.
    119
      /// @return The amount of assets withdrawn.
    120
      function withdraw(
    121
        uint256 reserveId,
    122
        uint256 amount,
    123
        address onBehalfOf
    124
      ) external returns (uint256, uint256);
    125
    126
      /// @notice Borrows a specified amount of underlying asset from the given reserve.
    127
      /// @dev It reverts if the reserve associated with the given reserve identifier is not listed.
    128
      /// @dev Caller must be `onBehalfOf` or an authorized position manager for `onBehalfOf`.
    129
      /// @dev Caller receives the underlying asset borrowed.
    130
      /// @param reserveId The identifier of the reserve.
    131
      /// @param amount The amount of asset to borrow.
    132
      /// @param onBehalfOf The owner of the position against which debt is generated.
    133
      /// @return The amount of shares borrowed.
    134
      /// @return The amount of assets borrowed.
    135
      function borrow(
    136
        uint256 reserveId,
    137
        uint256 amount,
    138
        address onBehalfOf
    139
      ) external returns (uint256, uint256);
    140
    141
      /// @notice Repays a specified amount of underlying asset to a given reserve.
    142
      /// @dev It reverts if the reserve associated with the given reserve identifier is not listed.
    143
      /// @dev The Spoke pulls the underlying asset from the caller, so prior approval is required.
    144
      /// @dev Caller must be `onBehalfOf` or an authorized position manager for `onBehalfOf`.
    145
      /// @param reserveId The identifier of the reserve.
    146
      /// @param amount The amount of asset to repay.
    147
      /// @param onBehalfOf The owner of the position whose debt is repaid.
    148
      /// @return The amount of shares repaid.
    149
      /// @return The amount of assets repaid.
    150
      function repay(
    151
        uint256 reserveId,
    152
        uint256 amount,
    153
        address onBehalfOf
    154
      ) external returns (uint256, uint256);
    155
    156
      /// @notice Liquidates a user position.
    157
      /// @dev It reverts if the reserves associated with any of the given reserve identifiers are not listed.
    158
      /// @dev The Spoke pulls underlying repaid debt assets from caller (Liquidator), hence it needs prior approval.
    159
      /// @param collateralReserveId The reserveId of the underlying asset used as collateral by the liquidated user.
    160
      /// @param debtReserveId The reserveId of the underlying asset borrowed by the liquidated user, to be repaid by Liquidator.
    161
      /// @param user The address of the user to liquidate.
    162
      /// @param debtToCover The desired amount of debt to cover.
    163
      /// @param receiveShares True to receive collateral in supplied shares, false to receive in underlying assets.
    164
      function liquidationCall(
    165
        uint256 collateralReserveId,
    166
        uint256 debtReserveId,
    167
        address user,
    168
        uint256 debtToCover,
    169
        bool receiveShares
    170
      ) external;
    171
    172
      /// @notice Returns the total amount of supplied assets of a given reserve.
    173
      /// @param reserveId The identifier of the reserve.
    174
      /// @return The amount of supplied assets.
    175
      function getReserveSuppliedAssets(uint256 reserveId) external view returns (uint256);
    176
    177
      /// @notice Returns the total amount of supplied shares of a given reserve.
    178
      /// @dev It reverts if the reserve associated with the given reserve identifier is not listed.
    179
      /// @param reserveId The identifier of the reserve.
    180
      /// @return The amount of supplied shares.
    181
      function getReserveSuppliedShares(uint256 reserveId) external view returns (uint256);
    182
    183
      /// @notice Returns the debt of a given reserve.
    184
      /// @dev It reverts if the reserve associated with the given reserve identifier is not listed.
    185
      /// @dev The total debt of the reserve is the sum of drawn debt and premium debt.
    186
      /// @param reserveId The identifier of the reserve.
    187
      /// @return The amount of drawn debt.
    188
      /// @return The amount of premium debt.
    189
      function getReserveDebt(uint256 reserveId) external view returns (uint256, uint256);
    190
    191
      /// @notice Returns the total debt of a given reserve.
    192
      /// @dev It reverts if the reserve associated with the given reserve identifier is not listed.
    193
      /// @dev The total debt of the reserve is the sum of drawn debt and premium debt.
    194
      /// @param reserveId The identifier of the reserve.
    195
      /// @return The total debt amount.
    196
      function getReserveTotalDebt(uint256 reserveId) external view returns (uint256);
    197
    198
      /// @notice Returns the amount of assets supplied by a specific user for a given reserve.
    199
      /// @dev It reverts if the reserve associated with the given reserve identifier is not listed.
    200
      /// @param reserveId The identifier of the reserve.
    201
      /// @param user The address of the user.
    202
      /// @return The amount of assets supplied by the user.
    203
      function getUserSuppliedAssets(uint256 reserveId, address user) external view returns (uint256);
    204
    205
      /// @notice Returns the amount of shares supplied by a specific user for a given reserve.
    206
      /// @dev It reverts if the reserve associated with the given reserve identifier is not listed.
    207
      /// @param reserveId The identifier of the reserve.
    208
      /// @param user The address of the user.
    209
      /// @return The amount of shares supplied by the user.
    210
      function getUserSuppliedShares(uint256 reserveId, address user) external view returns (uint256);
    211
    212
      /// @notice Returns the debt of a specific user for a given reserve.
    213
      /// @dev It reverts if the reserve associated with the given reserve identifier is not listed.
    214
      /// @dev The total debt of the user is the sum of drawn debt and premium debt.
    215
      /// @param reserveId The identifier of the reserve.
    216
      /// @param user The address of the user.
    217
      /// @return The amount of drawn debt.
    218
      /// @return The amount of premium debt.
    219
      function getUserDebt(uint256 reserveId, address user) external view returns (uint256, uint256);
    220
    221
      /// @notice Returns the total debt of a specific user for a given reserve.
    222
      /// @dev It reverts if the reserve associated with the given reserve identifier is not listed.
    223
      /// @dev The total debt of the user is the sum of drawn debt and premium debt.
    224
      /// @param reserveId The identifier of the reserve.
    225
      /// @param user The address of the user.
    226
      /// @return The total debt amount.
    227
      function getUserTotalDebt(uint256 reserveId, address user) external view returns (uint256);
    228
    229
      /// @notice Returns the full precision premium debt of a specific user for a given reserve.
    230
      /// @dev It reverts if the reserve associated with the given reserve identifier is not listed.
    231
      /// @param reserveId The identifier of the reserve.
    232
      /// @param user The address of the user.
    233
      /// @return The amount of premium debt, expressed in asset units and scaled by RAY.
    234
      function getUserPremiumDebtRay(uint256 reserveId, address user) external view returns (uint256);
    235
    }
    236
    0.0% src/spoke/interfaces/ISpokeConfigurator.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    import {ISpoke} from 'src/spoke/interfaces/ISpoke.sol';
    6
    7
    /// @title ISpokeConfigurator
    8
    /// @author Aave Labs
    9
    /// @notice Interface for the SpokeConfigurator.
    10
    interface ISpokeConfigurator {
    11
      /// @notice Emitted when the maximum allowed number of reserves for a spoke is updated.
    12
      /// @param spoke The address of the spoke.
    13
      /// @param maxReserves The new maximum number of reserves.
    14
      event UpdateMaxReserves(address indexed spoke, uint256 maxReserves);
    15
    16
      /// @dev Thrown upon adding a reserve when the maximum allowed number of reserves is already reached.
    17
      /// @param spoke The address of the spoke.
    18
      /// @param maxReserves The maximum allowed number of reserves.
    19
      error MaximumReservesReached(address spoke, uint256 maxReserves);
    20
    21
      /// @notice Updates the price source of a reserve.
    22
      /// @dev The price source must implement the AggregatorV3Interface.
    23
      /// @param spoke The address of the spoke.
    24
      /// @param reserveId The identifier of the reserve.
    25
      /// @param priceSource The new price source.
    26
      function updateReservePriceSource(address spoke, uint256 reserveId, address priceSource) external;
    27
    28
      /// @notice Updates the liquidation target health factor of a spoke.
    29
      /// @param spoke The address of the spoke.
    30
      /// @param targetHealthFactor The new liquidation target health factor.
    31
      function updateLiquidationTargetHealthFactor(address spoke, uint256 targetHealthFactor) external;
    32
    33
      /// @notice Updates the health factor for max liquidation bonus of a spoke.
    34
      /// @param spoke The address of the spoke.
    35
      /// @param healthFactorForMaxBonus The new health factor for max liquidation bonus.
    36
      function updateHealthFactorForMaxBonus(address spoke, uint256 healthFactorForMaxBonus) external;
    37
    38
      /// @notice Updates the liquidation bonus factor of a spoke.
    39
      /// @param spoke The address of the spoke.
    40
      /// @param liquidationBonusFactor The new liquidation bonus factor.
    41
      function updateLiquidationBonusFactor(address spoke, uint256 liquidationBonusFactor) external;
    42
    43
      /// @notice Updates the liquidation config of a spoke.
    44
      /// @param spoke The address of the spoke.
    45
      /// @param liquidationConfig The new liquidation config.
    46
      function updateLiquidationConfig(
    47
        address spoke,
    48
        ISpoke.LiquidationConfig calldata liquidationConfig
    49
      ) external;
    50
    51
      /// @notice Updates the maximum number of reserves allowed to exist on a spoke.
    52
      /// @dev It allows setting the maximum below the amount of reserves that currently exist.
    53
      /// @param spoke The address of the spoke.
    54
      /// @param maxReserves The new maximum number of reserves.
    55
      function updateMaxReserves(address spoke, uint256 maxReserves) external;
    56
    57
      /// @notice Adds a new reserve to a spoke.
    58
      /// @dev The asset corresponding to the reserve must be already listed on the Hub.
    59
      /// @dev The price source must implement the AggregatorV3Interface.
    60
      /// @param spoke The address of the spoke.
    61
      /// @param hub The address of the Hub where the asset corresponding to the reserve is listed.
    62
      /// @param assetId The identifier of the asset.
    63
      /// @param priceSource The address of the price source.
    64
      /// @param config The configuration of the reserve.
    65
      /// @param dynamicConfig The dynamic configuration of the reserve.
    66
      /// @return reserveId The identifier of the reserve.
    67
      function addReserve(
    68
        address spoke,
    69
        address hub,
    70
        uint256 assetId,
    71
        address priceSource,
    72
        ISpoke.ReserveConfig calldata config,
    73
        ISpoke.DynamicReserveConfig calldata dynamicConfig
    74
      ) external returns (uint256);
    75
    76
      /// @notice Updates the paused flag of a reserve.
    77
      /// @param spoke The address of the spoke.
    78
      /// @param reserveId The identifier of the reserve.
    79
      /// @param paused The new paused flag.
    80
      function updatePaused(address spoke, uint256 reserveId, bool paused) external;
    81
    82
      /// @notice Updates the frozen flag of a reserve.
    83
      /// @param spoke The address of the spoke.
    84
      /// @param reserveId The identifier of the reserve.
    85
      /// @param frozen The new frozen flag.
    86
      function updateFrozen(address spoke, uint256 reserveId, bool frozen) external;
    87
    88
      /// @notice Updates the borrowable flag of a reserve.
    89
      /// @param spoke The address of the spoke.
    90
      /// @param reserveId The identifier of the reserve.
    91
      /// @param borrowable The new borrowable flag.
    92
      function updateBorrowable(address spoke, uint256 reserveId, bool borrowable) external;
    93
    94
      /// @notice Updates the liquidatable flag of a reserve.
    95
      /// @param spoke The address of the spoke.
    96
      /// @param reserveId The identifier of the reserve.
    97
      /// @param liquidatable The new liquidatable flag.
    98
      function updateLiquidatable(address spoke, uint256 reserveId, bool liquidatable) external;
    99
    100
      /// @notice Updates whether receiving shares on liquidation is enabled.
    101
      /// @param spoke The address of the spoke.
    102
      /// @param reserveId The identifier of the reserve.
    103
      /// @param receiveSharesEnabled The new receiveSharesEnabled flag.
    104
      function updateReceiveSharesEnabled(
    105
        address spoke,
    106
        uint256 reserveId,
    107
        bool receiveSharesEnabled
    108
      ) external;
    109
    110
      /// @notice Updates the collateral risk of a reserve.
    111
      /// @param spoke The address of the spoke.
    112
      /// @param reserveId The identifier of the reserve.
    113
      /// @param collateralRisk The new collateral risk.
    114
      function updateCollateralRisk(address spoke, uint256 reserveId, uint256 collateralRisk) external;
    115
    116
      /// @notice Adds a dynamic config to a reserve, identical to the latest one but with the specified collateral factor.
    117
      /// @param spoke The address of the spoke.
    118
      /// @param reserveId The identifier of the reserve.
    119
      /// @param collateralFactor The new collateral factor.
    120
      /// @return The dynamicConfigKey of the added dynamic configuration.
    121
      function addCollateralFactor(
    122
        address spoke,
    123
        uint256 reserveId,
    124
        uint16 collateralFactor
    125
      ) external returns (uint24);
    126
    127
      /// @notice Updates an existing collateral factor of a reserve at the specified key.
    128
      /// @param spoke The address of the spoke.
    129
      /// @param reserveId The identifier of the reserve.
    130
      /// @param dynamicConfigKey The key of the dynamic config to update.
    131
      /// @param collateralFactor The new collateral factor.
    132
      function updateCollateralFactor(
    133
        address spoke,
    134
        uint256 reserveId,
    135
        uint24 dynamicConfigKey,
    136
        uint16 collateralFactor
    137
      ) external;
    138
    139
      /// @notice Adds a dynamic config to a reserve, identical to the latest one but with the specified max liquidation bonus.
    140
      /// @param spoke The address of the spoke.
    141
      /// @param reserveId The identifier of the reserve.
    142
      /// @param maxLiquidationBonus The new max liquidation bonus.
    143
      /// @return The dynamicConfigKey of the added dynamic configuration.
    144
      function addMaxLiquidationBonus(
    145
        address spoke,
    146
        uint256 reserveId,
    147
        uint256 maxLiquidationBonus
    148
      ) external returns (uint24);
    149
    150
      /// @notice Updates an existing liquidation bonus of a reserve at the specified key.
    151
      /// @param spoke The address of the spoke.
    152
      /// @param reserveId The identifier of the reserve.
    153
      /// @param dynamicConfigKey The key of the dynamic config to update.
    154
      /// @param maxLiquidationBonus The new liquidation bonus.
    155
      function updateMaxLiquidationBonus(
    156
        address spoke,
    157
        uint256 reserveId,
    158
        uint24 dynamicConfigKey,
    159
        uint256 maxLiquidationBonus
    160
      ) external;
    161
    162
      /// @notice Adds a dynamic config to a reserve, identical to the latest one but with the specified liquidation fee.
    163
      /// @param spoke The address of the spoke.
    164
      /// @param reserveId The identifier of the reserve.
    165
      /// @param liquidationFee The new liquidation fee.
    166
      /// @return The dynamicConfigKey of the added dynamic configuration.
    167
      function addLiquidationFee(
    168
        address spoke,
    169
        uint256 reserveId,
    170
        uint256 liquidationFee
    171
      ) external returns (uint24);
    172
    173
      /// @notice Updates an existing liquidation fee of a reserve at the specified key.
    174
      /// @param spoke The address of the spoke.
    175
      /// @param reserveId The identifier of the reserve.
    176
      /// @param dynamicConfigKey The key of the dynamic config to update.
    177
      /// @param liquidationFee The new liquidation fee.
    178
      function updateLiquidationFee(
    179
        address spoke,
    180
        uint256 reserveId,
    181
        uint24 dynamicConfigKey,
    182
        uint256 liquidationFee
    183
      ) external;
    184
    185
      /// @notice Adds a dynamic config to a reserve.
    186
      /// @param spoke The address of the spoke.
    187
      /// @param reserveId The identifier of the reserve.
    188
      /// @param dynamicConfig The new dynamic config.
    189
      /// @return dynamicConfigKey The key of the added dynamic config.
    190
      function addDynamicReserveConfig(
    191
        address spoke,
    192
        uint256 reserveId,
    193
        ISpoke.DynamicReserveConfig calldata dynamicConfig
    194
      ) external returns (uint24);
    195
    196
      /// @notice Updates the dynamic config of a reserve at the specified key.
    197
      /// @param spoke The address of the spoke.
    198
      /// @param reserveId The identifier of the reserve.
    199
      /// @param dynamicConfigKey The key of the dynamic config to update.
    200
      /// @param dynamicConfig The new dynamic config.
    201
      function updateDynamicReserveConfig(
    202
        address spoke,
    203
        uint256 reserveId,
    204
        uint24 dynamicConfigKey,
    205
        ISpoke.DynamicReserveConfig calldata dynamicConfig
    206
      ) external;
    207
    208
      /// @notice Pauses all reserves of a spoke.
    209
      /// @param spoke The address of the spoke.
    210
      function pauseAllReserves(address spoke) external;
    211
    212
      /// @notice Freezes all reserves of a spoke.
    213
      /// @param spoke The address of the spoke.
    214
      function freezeAllReserves(address spoke) external;
    215
    216
      /// @notice Updates the active flag of a spoke's position manager.
    217
      /// @param spoke The address of the spoke.
    218
      /// @param positionManager The address of the position manager.
    219
      /// @param active The new active flag.
    220
      function updatePositionManager(address spoke, address positionManager, bool active) external;
    221
    222
      /// @notice Returns the maximum number of reserves allowed to exist on a spoke.
    223
      /// @param spoke The address of the spoke.
    224
      /// @return The maximum number of reserves.
    225
      function getMaxReserves(address spoke) external view returns (uint256);
    226
    }
    227
    0.0% src/spoke/interfaces/ITreasurySpoke.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    import {IHubBase} from 'src/hub/interfaces/IHubBase.sol';
    6
    import {ISpokeBase} from 'src/spoke/interfaces/ISpokeBase.sol';
    7
    8
    /// @title ITreasurySpoke
    9
    /// @author Aave Labs
    10
    /// @notice Interface for the TreasurySpoke.
    11
    interface ITreasurySpoke is ISpokeBase {
    12
      /// @notice Thrown when an unsupported action is attempted.
    13
      error UnsupportedAction();
    14
    15
      /// @notice Thrown when the given address is invalid.
    16
      error InvalidAddress();
    17
    18
      /// @notice Supplies a specified amount of the underlying asset to a given reserve.
    19
      /// @dev The Spoke pulls the underlying asset from the caller, so prior approval is required.
    20
      /// @dev The reserve identifier must match the asset identifier in the Hub.
    21
      /// @param reserveId The identifier of the reserve.
    22
      /// @param amount The amount of asset to supply.
    23
      /// @param onBehalfOf Unused parameter for this spoke.
    24
      /// @return The amount of shares supplied.
    25
      /// @return The amount of assets supplied.
    26
      function supply(
    27
        uint256 reserveId,
    28
        uint256 amount,
    29
        address onBehalfOf
    30
      ) external returns (uint256, uint256);
    31
    32
      /// @notice Withdraws a specified amount of underlying asset from the given reserve.
    33
      /// @dev Providing an amount greater than the maximum withdrawable value signals a full withdrawal.
    34
      /// @dev The reserve identifier must match the asset identifier in the Hub.
    35
      /// @param reserveId The identifier of the reserve.
    36
      /// @param amount The amount of asset to withdraw.
    37
      /// @param onBehalfOf Unused parameter for this spoke.
    38
      /// @return The amount of shares withdrawn.
    39
      /// @return The amount of assets withdrawn.
    40
      function withdraw(
    41
        uint256 reserveId,
    42
        uint256 amount,
    43
        address onBehalfOf
    44
      ) external returns (uint256, uint256);
    45
    46
      /// @notice Transfers a specified amount of ERC20 tokens from this contract.
    47
      /// @param token The address of the ERC20 token to transfer.
    48
      /// @param to The recipient address.
    49
      /// @param amount The amount of tokens to transfer.
    50
      function transfer(address token, address to, uint256 amount) external;
    51
    52
      /// @notice Returns the amount of assets supplied.
    53
      /// @dev The reserve identifier must match the asset identifier in the Hub.
    54
      /// @param reserveId The identifier of the reserve.
    55
      /// @return The amount of assets supplied.
    56
      function getSuppliedAmount(uint256 reserveId) external view returns (uint256);
    57
    58
      /// @notice Returns the amount of shares supplied.
    59
      /// @dev Shares are denominated relative to the supply side.
    60
      /// @dev The reserve identifier must match the asset identifier in the Hub.
    61
      /// @param reserveId The identifier of the reserve.
    62
      /// @return The amount of shares supplied.
    63
      function getSuppliedShares(uint256 reserveId) external view returns (uint256);
    64
    65
      /// @notice Returns the interface of the associated Hub.
    66
      /// @return The HubBase interface.
    67
      function HUB() external view returns (IHubBase);
    68
    }
    69
    100.0% src/spoke/libraries/KeyValueList.sol
    Lines covered: 26 / 26 (100.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.20;
    4
    5
    import {Arrays} from 'src/dependencies/openzeppelin/Arrays.sol';
    6
    7
    /// @title KeyValueList Library
    8
    /// @author Aave Labs
    9
    /// @notice Library to pack key-value pairs in a list.
    10
    /// @dev The `sortByKey` helper sorts by ascending order of the `key` & in case of collision by descending order of the `value`.
    11
    /// @dev This is achieved by sorting the packed `key-value` pair in descending order, but storing the invert of the `key` (ie `_MAX_KEY - key`).
    12
    /// @dev Uninitialized keys are returned as (key: 0, value: 0) and are placed at the end of the list after sorting.
    13
    library KeyValueList {
    14
      /// @notice Thrown when adding a key which can't be stored in `_KEY_BITS` or value in `_VALUE_BITS`.
    15
      error MaxDataSizeExceeded();
    16
    17
      struct List {
    18
        uint256[] _inner;
    19
      }
    20
    21
      uint256 internal constant _KEY_BITS = 32;
    22
      uint256 internal constant _VALUE_BITS = 224;
    23
      uint256 internal constant _MAX_KEY = (1 << _KEY_BITS) - 1;
    24
      uint256 internal constant _MAX_VALUE = (1 << _VALUE_BITS) - 1;
    25
      uint256 internal constant _KEY_SHIFT = 256 - _KEY_BITS;
    26
    27
      /// @notice Allocates memory for a KeyValue list of `size` elements.
    28
      function init(uint256 size) internal pure returns (List memory) {
    29
        return List(new uint256[](size));
    30
      }
    31
    32
      /// @notice Returns the length of the list.
    33
      function length(List memory self) internal pure returns (uint256) {
    34
        return self._inner.length;
    35
      }
    36
    37
      /// @notice Inserts packed `key`, `value` at `idx`. Reverts if data exceeds maximum allowed size.
    38
      /// @dev Reverts if `key` equals or exceeds the `_MAX_KEY` value and reverts if `value` equals or exceeds the `_MAX_VALUE` value.
    39
      function add(List memory self, uint256 idx, uint256 key, uint256 value) internal pure {
    40
        require(key < _MAX_KEY && value < _MAX_VALUE, MaxDataSizeExceeded());
    41
        self._inner[idx] = pack(key, value);
    42
      }
    43
    44
      /// @notice Returns the key-value pair at the given index.
    45
      /// @dev Uninitialized keys are returned as (key: 0, value: 0).
    46
      function get(List memory self, uint256 idx) internal pure returns (uint256, uint256) {
    47
        return unpack(self._inner[idx]);
    48
      }
    49
    50
      /// @notice Sorts the list in-place by ascending order of `key`, and descending order of `value` on collision.
    51
      /// @dev All uninitialized keys are placed at the end of the list after sorting.
    52
      /// @dev Since `key` is in the MSB, we can sort by the key by sorting the array in descending order
    53
      /// (so the keys are in ascending order when unpacking, due to the inversion when packed).
    54
      function sortByKey(List memory self) internal pure {
    55
        Arrays.sort(self._inner, gtComparator);
    56
      }
    57
    58
      /// @notice Packs a given `key`, `value` pair into a single word.
    59
      /// @dev Bound checks are expected to be done before packing.
    60
      function pack(uint256 key, uint256 value) internal pure returns (uint256) {
    61
        return ((_MAX_KEY - key) << _KEY_SHIFT) | value;
    62
      }
    63
    64
      /// @notice Unpacks `key` from a previously packed word containing `key` and `value`.
    65
      /// @dev The key is stored in the most significant bits of the word.
    66
      function unpackKey(uint256 data) internal pure returns (uint256) {
    67
        return _MAX_KEY - (data >> _KEY_SHIFT);
    68
      }
    69
    70
      /// @notice Unpacks `value` from a previously packed word containing `key` and `value`.
    71
      /// @dev The value is stored in the least significant bits of the word.
    72
      function unpackValue(uint256 data) internal pure returns (uint256) {
    73
        return data & ((1 << _KEY_SHIFT) - 1);
    74
      }
    75
    76
      /// @notice Unpacks both `key` and `value` from a previously packed word containing `key` and `value`.
    77
      /// @dev Uninitialized keys are returned as (key: 0, value: 0).
    78
      /// @param data The packed word containing `key` and `value`.
    79
      function unpack(uint256 data) internal pure returns (uint256, uint256) {
    80
        if (data == 0) return (0, 0);
    81
        return (unpackKey(data), unpackValue(data));
    82
      }
    83
    84
      /// @notice Comparator function performing greater-than comparison.
    85
      /// @return True if `a` is greater than `b`.
    86
      function gtComparator(uint256 a, uint256 b) internal pure returns (bool) {
    87
        return a > b;
    88
      }
    89
    }
    90
    46.0% src/spoke/libraries/LiquidationLogic.sol
    Lines covered: 104 / 222 (46.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.20;
    4
    5
    import {SafeCast} from 'src/dependencies/openzeppelin/SafeCast.sol';
    6
    import {SafeERC20, IERC20} from 'src/dependencies/openzeppelin/SafeERC20.sol';
    7
    import {MathUtils} from 'src/libraries/math/MathUtils.sol';
    8
    import {PercentageMath} from 'src/libraries/math/PercentageMath.sol';
    9
    import {WadRayMath} from 'src/libraries/math/WadRayMath.sol';
    10
    import {PositionStatusMap} from 'src/spoke/libraries/PositionStatusMap.sol';
    11
    import {UserPositionDebt} from 'src/spoke/libraries/UserPositionDebt.sol';
    12
    import {ReserveFlags, ReserveFlagsMap} from 'src/spoke/libraries/ReserveFlagsMap.sol';
    13
    import {IHubBase} from 'src/hub/interfaces/IHubBase.sol';
    14
    import {IAaveOracle} from 'src/spoke/interfaces/IAaveOracle.sol';
    15
    import {ISpoke, ISpokeBase} from 'src/spoke/interfaces/ISpoke.sol';
    16
    17
    /// @title LiquidationLogic library
    18
    /// @author Aave Labs
    19
    /// @notice Implements the logic for liquidations.
    20
    library LiquidationLogic {
    21
      using SafeCast for *;
    22
      using SafeERC20 for IERC20;
    23
      using MathUtils for *;
    24
      using PercentageMath for uint256;
    25
      using WadRayMath for uint256;
    26
      using UserPositionDebt for ISpoke.UserPosition;
    27
      using ReserveFlagsMap for ReserveFlags;
    28
      using PositionStatusMap for ISpoke.PositionStatus;
    29
    30
      struct LiquidateUserParams {
    31
        uint256 collateralReserveId;
    32
        uint256 debtReserveId;
    33
        address oracle;
    34
        address user;
    35
        uint256 debtToCover;
    36
        uint256 healthFactor;
    37
        uint256 drawnDebt;
    38
        uint256 premiumDebtRay;
    39
        uint256 drawnIndex;
    40
        uint256 totalDebtValue;
    41
        address liquidator;
    42
        uint256 activeCollateralCount;
    43
        uint256 borrowedCount;
    44
        bool receiveShares;
    45
      }
    46
    47
      struct LiquidateCollateralParams {
    48
        uint256 collateralToLiquidate;
    49
        uint256 collateralToLiquidator;
    50
        address liquidator;
    51
        bool receiveShares;
    52
      }
    53
    54
      struct LiquidateDebtParams {
    55
        uint256 debtReserveId;
    56
        uint256 debtToLiquidate;
    57
        uint256 premiumDebtRay;
    58
        uint256 drawnIndex;
    59
        address liquidator;
    60
      }
    61
    62
      struct ValidateLiquidationCallParams {
    63
        address user;
    64
        address liquidator;
    65
        ReserveFlags collateralReserveFlags;
    66
        ReserveFlags debtReserveFlags;
    67
        uint256 collateralReserveBalance;
    68
        uint256 debtReserveBalance;
    69
        uint256 debtToCover;
    70
        uint256 collateralFactor;
    71
        bool isUsingAsCollateral;
    72
        uint256 healthFactor;
    73
        bool receiveShares;
    74
      }
    75
    76
      struct CalculateDebtToTargetHealthFactorParams {
    77
        uint256 totalDebtValue;
    78
        uint256 debtAssetUnit;
    79
        uint256 debtAssetPrice;
    80
        uint256 collateralFactor;
    81
        uint256 liquidationBonus;
    82
        uint256 healthFactor;
    83
        uint256 targetHealthFactor;
    84
      }
    85
    86
      struct CalculateDebtToLiquidateParams {
    87
        uint256 debtReserveBalance;
    88
        uint256 totalDebtValue;
    89
        uint256 debtAssetUnit;
    90
        uint256 debtAssetPrice;
    91
        uint256 debtToCover;
    92
        uint256 collateralFactor;
    93
        uint256 liquidationBonus;
    94
        uint256 healthFactor;
    95
        uint256 targetHealthFactor;
    96
      }
    97
    98
      struct CalculateLiquidationAmountsParams {
    99
        uint256 collateralReserveBalance;
    100
        uint256 collateralAssetUnit;
    101
        uint256 collateralAssetPrice;
    102
        uint256 debtReserveBalance;
    103
        uint256 totalDebtValue;
    104
        uint256 debtAssetUnit;
    105
        uint256 debtAssetPrice;
    106
        uint256 debtToCover;
    107
        uint256 collateralFactor;
    108
        uint256 healthFactorForMaxBonus;
    109
        uint256 liquidationBonusFactor;
    110
        uint256 maxLiquidationBonus;
    111
        uint256 targetHealthFactor;
    112
        uint256 healthFactor;
    113
        uint256 liquidationFee;
    114
      }
    115
    116
      struct LiquidationAmounts {
    117
        uint256 collateralToLiquidate;
    118
        uint256 collateralToLiquidator;
    119
        uint256 debtToLiquidate;
    120
      }
    121
    122
      // see ISpoke.HEALTH_FACTOR_LIQUIDATION_THRESHOLD docs
    123
      uint64 public constant HEALTH_FACTOR_LIQUIDATION_THRESHOLD = 1e18;
    124
    125
      // see ISpoke.DUST_LIQUIDATION_THRESHOLD docs
    126
      uint256 public constant DUST_LIQUIDATION_THRESHOLD = 1000e26;
    127
    128
      /// @notice Liquidates a user position.
    129
      /// @param collateralReserve The collateral reserve to seize during liquidation.
    130
      /// @param debtReserve The debt reserve to repay during liquidation.
    131
      /// @param positions The mapping of positions per reserve per user.
    132
      /// @param positionStatus The mapping of position status per user.
    133
      /// @param liquidationConfig The liquidation config.
    134
      /// @param collateralDynConfig The collateral dynamic config.
    135
      /// @param params The liquidate user params.
    136
      /// @return True if the liquidation results in deficit.
    137
      function liquidateUser(
    138
        ISpoke.Reserve storage collateralReserve,
    139
        ISpoke.Reserve storage debtReserve,
    140
        mapping(address user => mapping(uint256 reserveId => ISpoke.UserPosition)) storage positions,
    141
        mapping(address user => ISpoke.PositionStatus) storage positionStatus,
    142
        ISpoke.LiquidationConfig storage liquidationConfig,
    143
        ISpoke.DynamicReserveConfig storage collateralDynConfig,
    144
        LiquidateUserParams memory params
    145
      ) external returns (bool) {
    146
        uint256 collateralReserveBalance = collateralReserve.hub.previewRemoveByShares(
    147
          collateralReserve.assetId,
    148
          positions[params.user][params.collateralReserveId].suppliedShares
    149
        );
    150
        _validateLiquidationCall(
    151
          ValidateLiquidationCallParams({
    152
            user: params.user,
    153
            liquidator: params.liquidator,
    154
            collateralReserveFlags: collateralReserve.flags,
    155
            debtReserveFlags: debtReserve.flags,
    156
            collateralReserveBalance: collateralReserveBalance,
    157
            debtReserveBalance: params.drawnDebt + params.premiumDebtRay.fromRayUp(),
    158
            debtToCover: params.debtToCover,
    159
            collateralFactor: collateralDynConfig.collateralFactor,
    160
            isUsingAsCollateral: positionStatus[params.user].isUsingAsCollateral(
    161
              params.collateralReserveId
    162
            ),
    163
            healthFactor: params.healthFactor,
    164
            receiveShares: params.receiveShares
    165
          })
    166
        );
    167
    168
        LiquidationAmounts memory liquidationAmounts = _calculateLiquidationAmounts(
    169
          CalculateLiquidationAmountsParams({
    170
            collateralReserveBalance: collateralReserveBalance,
    171
            collateralAssetUnit: MathUtils.uncheckedExp(10, collateralReserve.decimals),
    172
            collateralAssetPrice: IAaveOracle(params.oracle).getReservePrice(
    173
              params.collateralReserveId
    174
            ),
    175
            debtReserveBalance: params.drawnDebt + params.premiumDebtRay.fromRayUp(),
    176
            totalDebtValue: params.totalDebtValue,
    177
            debtAssetUnit: MathUtils.uncheckedExp(10, debtReserve.decimals),
    178
            debtAssetPrice: IAaveOracle(params.oracle).getReservePrice(params.debtReserveId),
    179
            debtToCover: params.debtToCover,
    180
            collateralFactor: collateralDynConfig.collateralFactor,
    181
            healthFactorForMaxBonus: liquidationConfig.healthFactorForMaxBonus,
    182
            liquidationBonusFactor: liquidationConfig.liquidationBonusFactor,
    183
            maxLiquidationBonus: collateralDynConfig.maxLiquidationBonus,
    184
            targetHealthFactor: liquidationConfig.targetHealthFactor,
    185
            healthFactor: params.healthFactor,
    186
            liquidationFee: collateralDynConfig.liquidationFee
    187
          })
    188
        );
    189
    190
        (
    191
          uint256 collateralSharesToLiquidate,
    192
          uint256 collateralSharesToLiquidator,
    193
          bool isCollateralPositionEmpty
    194
        ) = _liquidateCollateral(
    195
            collateralReserve,
    196
            positions[params.user][params.collateralReserveId],
    197
            positions[params.liquidator][params.collateralReserveId],
    198
            LiquidateCollateralParams({
    199
              collateralToLiquidate: liquidationAmounts.collateralToLiquidate,
    200
              collateralToLiquidator: liquidationAmounts.collateralToLiquidator,
    201
              liquidator: params.liquidator,
    202
              receiveShares: params.receiveShares
    203
            })
    204
          );
    205
    206
        (
    207
          uint256 drawnSharesToLiquidate,
    208
          IHubBase.PremiumDelta memory premiumDelta,
    209
          bool isDebtPositionEmpty
    210
        ) = _liquidateDebt(
    211
            debtReserve,
    212
            positions[params.user][params.debtReserveId],
    213
            positionStatus[params.user],
    214
            LiquidateDebtParams({
    215
              debtReserveId: params.debtReserveId,
    216
              debtToLiquidate: liquidationAmounts.debtToLiquidate,
    217
              premiumDebtRay: params.premiumDebtRay,
    218
              drawnIndex: params.drawnIndex,
    219
              liquidator: params.liquidator
    220
            })
    221
          );
    222
    223
        emit ISpokeBase.LiquidationCall(
    224
          params.collateralReserveId,
    225
          params.debtReserveId,
    226
          params.user,
    227
          params.liquidator,
    228
          params.receiveShares,
    229
          liquidationAmounts.debtToLiquidate,
    230
          drawnSharesToLiquidate,
    231
          premiumDelta,
    232
          liquidationAmounts.collateralToLiquidate,
    233
          collateralSharesToLiquidate,
    234
          collateralSharesToLiquidator
    235
        );
    236
    237
        return
    238
          _evaluateDeficit({
    239
            isCollateralPositionEmpty: isCollateralPositionEmpty,
    240
            isDebtPositionEmpty: isDebtPositionEmpty,
    241
            activeCollateralCount: params.activeCollateralCount,
    242
            borrowedCount: params.borrowedCount
    243
          });
    244
      }
    245
    246
      /// @notice Calculates the liquidation bonus at a given health factor.
    247
      /// @dev Liquidation Bonus is expressed as a BPS value greater than `PercentageMath.PERCENTAGE_FACTOR`.
    248
      /// @param healthFactorForMaxBonus The health factor for max bonus.
    249
      /// @param liquidationBonusFactor The liquidation bonus factor.
    250
      /// @param healthFactor The health factor.
    251
      /// @param maxLiquidationBonus The max liquidation bonus.
    252
      /// @return The liquidation bonus.
    253
      function calculateLiquidationBonus(
    254
        uint256 healthFactorForMaxBonus,
    255
        uint256 liquidationBonusFactor,
    256
        uint256 healthFactor,
    257
        uint256 maxLiquidationBonus
    258
      ) internal pure returns (uint256) {
    259
        if (healthFactor <= healthFactorForMaxBonus) {
    260
          return maxLiquidationBonus;
    261
        }
    262
    263
        uint256 minLiquidationBonus = (maxLiquidationBonus - PercentageMath.PERCENTAGE_FACTOR)
    264
          .percentMulDown(liquidationBonusFactor) + PercentageMath.PERCENTAGE_FACTOR;
    265
    266
        // linear interpolation between min and max
    267
        // denominator cannot be zero as healthFactorForMaxBonus is always < HEALTH_FACTOR_LIQUIDATION_THRESHOLD
    268
        return
    269
          minLiquidationBonus +
    270
          (maxLiquidationBonus - minLiquidationBonus).mulDivDown(
    271
            HEALTH_FACTOR_LIQUIDATION_THRESHOLD - healthFactor,
    272
            HEALTH_FACTOR_LIQUIDATION_THRESHOLD - healthFactorForMaxBonus
    273
          );
    274
      }
    275
    276
      /// @dev Invoked by `liquidateUser` method.
    277
      /// @return The total amount of collateral shares to be liquidated.
    278
      /// @return The amount of collateral shares that the liquidator receives.
    279
      /// @return True if the user collateral position becomes empty after removing.
    280
      function _liquidateCollateral(
    281
        ISpoke.Reserve storage collateralReserve,
    282
        ISpoke.UserPosition storage collateralPosition,
    283
        ISpoke.UserPosition storage liquidatorCollateralPosition,
    284
        LiquidateCollateralParams memory params
    285
      ) internal returns (uint256, uint256, bool) {
    286
        IHubBase hub = collateralReserve.hub;
    287
        uint256 assetId = collateralReserve.assetId;
    288
    289
        uint256 sharesToLiquidate = hub.previewRemoveByAssets(assetId, params.collateralToLiquidate);
    290
        uint120 userSuppliedShares = collateralPosition.suppliedShares - sharesToLiquidate.toUint120();
    291
    292
        uint256 sharesToLiquidator;
    293
        if (params.collateralToLiquidator > 0) {
    294
          if (params.receiveShares) {
    295
            sharesToLiquidator = hub.previewAddByAssets(assetId, params.collateralToLiquidator);
    296
            if (sharesToLiquidator > 0) {
    297
              liquidatorCollateralPosition.suppliedShares += sharesToLiquidator.toUint120();
    298
            }
    299
          } else {
    300
            sharesToLiquidator = hub.remove(assetId, params.collateralToLiquidator, params.liquidator);
    301
          }
    302
        }
    303
    304
        collateralPosition.suppliedShares = userSuppliedShares;
    305
    306
        if (sharesToLiquidate > sharesToLiquidator) {
    307
          hub.payFeeShares(assetId, sharesToLiquidate.uncheckedSub(sharesToLiquidator));
    308
        }
    309
    310
        return (sharesToLiquidate, sharesToLiquidator, userSuppliedShares == 0);
    311
      }
    312
    313
      /// @dev Invoked by `liquidateUser` method.
    314
      /// @return The amount of drawn shares to be liquidated.
    315
      /// @return A struct representing the changes to premium debt after liquidation.
    316
      /// @return True if the debt position becomes zero after restoring.
    317
      function _liquidateDebt(
    318
        ISpoke.Reserve storage debtReserve,
    319
        ISpoke.UserPosition storage debtPosition,
    320
        ISpoke.PositionStatus storage positionStatus,
    321
        LiquidateDebtParams memory params
    322
      ) internal returns (uint256, IHubBase.PremiumDelta memory, bool) {
    323
        uint256 premiumDebtToLiquidateRay = params.debtToLiquidate.toRay().min(params.premiumDebtRay);
    324
        uint256 drawnDebtLiquidated = params.debtToLiquidate - premiumDebtToLiquidateRay.fromRayUp();
    325
        uint256 drawnSharesLiquidated = drawnDebtLiquidated.rayDivDown(params.drawnIndex);
    326
    327
        IHubBase.PremiumDelta memory premiumDelta = debtPosition.getPremiumDelta({
    328
          drawnSharesTaken: drawnSharesLiquidated,
    329
          drawnIndex: params.drawnIndex,
    330
          riskPremium: positionStatus.riskPremium,
    331
          restoredPremiumRay: premiumDebtToLiquidateRay
    332
        });
    333
    334
        IERC20(debtReserve.underlying).safeTransferFrom(
    335
          params.liquidator,
    336
          address(debtReserve.hub),
    337
          params.debtToLiquidate
    338
        );
    339
        debtReserve.hub.restore(debtReserve.assetId, drawnDebtLiquidated, premiumDelta);
    340
    341
        debtPosition.applyPremiumDelta(premiumDelta);
    342
        debtPosition.drawnShares -= drawnSharesLiquidated.toUint120();
    343
        if (debtPosition.drawnShares == 0) {
    344
          positionStatus.setBorrowing(params.debtReserveId, false);
    345
          return (drawnSharesLiquidated, premiumDelta, true);
    346
        }
    347
    348
        return (drawnSharesLiquidated, premiumDelta, false);
    349
      }
    350
    351
      /// @notice Validates the liquidation call.
    352
      /// @param params The validate liquidation call params.
    353
      function _validateLiquidationCall(ValidateLiquidationCallParams memory params) internal pure {
    354
        require(params.user != params.liquidator, ISpoke.SelfLiquidation());
    355
        require(params.debtToCover > 0, ISpoke.InvalidDebtToCover());
    356
        require(
    357
          !params.collateralReserveFlags.paused() && !params.debtReserveFlags.paused(),
    358
          ISpoke.ReservePaused()
    359
        );
    360
        require(params.collateralReserveBalance > 0, ISpoke.ReserveNotSupplied());
    361
        require(params.debtReserveBalance > 0, ISpoke.ReserveNotBorrowed());
    362
        require(params.collateralReserveFlags.liquidatable(), ISpoke.CollateralCannotBeLiquidated());
    363
        require(
    364
          params.healthFactor < HEALTH_FACTOR_LIQUIDATION_THRESHOLD,
    365
          ISpoke.HealthFactorNotBelowThreshold()
    366
        );
    367
        require(
    368
          params.collateralFactor > 0 && params.isUsingAsCollateral,
    369
          ISpoke.ReserveNotEnabledAsCollateral()
    370
        );
    371
        if (params.receiveShares) {
    372
          require(
    373
            !params.collateralReserveFlags.frozen() &&
    374
              params.collateralReserveFlags.receiveSharesEnabled(),
    375
            ISpoke.CannotReceiveShares()
    376
          );
    377
        }
    378
      }
    379
    380
      /// @notice Calculates the liquidation amounts.
    381
      /// @dev Invoked by `liquidateUser` method.
    382
      function _calculateLiquidationAmounts(
    383
        CalculateLiquidationAmountsParams memory params
    384
      ) internal pure returns (LiquidationAmounts memory) {
    385
        uint256 liquidationBonus = calculateLiquidationBonus({
    386
          healthFactorForMaxBonus: params.healthFactorForMaxBonus,
    387
          liquidationBonusFactor: params.liquidationBonusFactor,
    388
          healthFactor: params.healthFactor,
    389
          maxLiquidationBonus: params.maxLiquidationBonus
    390
        });
    391
    392
        // To prevent accumulation of dust, one of the following conditions is enforced:
    393
        // 1. liquidate all debt
    394
        // 2. liquidate all collateral
    395
        // 3. leave at least `DUST_LIQUIDATION_THRESHOLD` of collateral and debt (in value terms)
    396
        uint256 debtToLiquidate = _calculateDebtToLiquidate(
    397
          CalculateDebtToLiquidateParams({
    398
            debtReserveBalance: params.debtReserveBalance,
    399
            totalDebtValue: params.totalDebtValue,
    400
            debtAssetUnit: params.debtAssetUnit,
    401
            debtAssetPrice: params.debtAssetPrice,
    402
            debtToCover: params.debtToCover,
    403
            collateralFactor: params.collateralFactor,
    404
            liquidationBonus: liquidationBonus,
    405
            healthFactor: params.healthFactor,
    406
            targetHealthFactor: params.targetHealthFactor
    407
          })
    408
        );
    409
    410
        uint256 collateralToLiquidate = debtToLiquidate.mulDivDown(
    411
          params.debtAssetPrice * params.collateralAssetUnit * liquidationBonus,
    412
          params.debtAssetUnit * params.collateralAssetPrice * PercentageMath.PERCENTAGE_FACTOR
    413
        );
    414
    415
        bool leavesCollateralDust = collateralToLiquidate < params.collateralReserveBalance &&
    416
          (params.collateralReserveBalance - collateralToLiquidate).mulDivDown(
    417
            params.collateralAssetPrice.toWad(),
    418
            params.collateralAssetUnit
    419
          ) <
    420
          DUST_LIQUIDATION_THRESHOLD;
    421
    422
        if (
    423
          collateralToLiquidate > params.collateralReserveBalance ||
    424
          (leavesCollateralDust && debtToLiquidate < params.debtReserveBalance)
    425
        ) {
    426
          collateralToLiquidate = params.collateralReserveBalance;
    427
    428
          // - `debtToLiquidate` is decreased if `collateralToLiquidate > params.collateralReserveBalance` (if so, debt dust could remain).
    429
          // - `debtToLiquidate` is increased if `(leavesCollateralDust && debtToLiquidate < params.debtReserveBalance)`, ensuring collateral reserve
    430
          //   is fully liquidated (potentially bypassing the target health factor). Can only increase by at most `DUST_LIQUIDATION_THRESHOLD` (in
    431
          //   value terms). Since debt dust condition was enforced, it is guaranteed that `debtToLiquidate` will never exceed `params.debtReserveBalance`.
    432
          debtToLiquidate = collateralToLiquidate.mulDivUp(
    433
            params.collateralAssetPrice * params.debtAssetUnit * PercentageMath.PERCENTAGE_FACTOR,
    434
            params.debtAssetPrice * params.collateralAssetUnit * liquidationBonus
    435
          );
    436
        }
    437
    438
        // revert if the liquidator does not cover the necessary debt to prevent dust from remaining
    439
        require(params.debtToCover >= debtToLiquidate, ISpoke.MustNotLeaveDust());
    440
    441
        uint256 collateralToLiquidator = collateralToLiquidate -
    442
          collateralToLiquidate.mulDivDown(
    443
            params.liquidationFee * (liquidationBonus - PercentageMath.PERCENTAGE_FACTOR),
    444
            liquidationBonus * PercentageMath.PERCENTAGE_FACTOR
    445
          );
    446
    447
        return
    448
          LiquidationAmounts({
    449
            collateralToLiquidate: collateralToLiquidate,
    450
            collateralToLiquidator: collateralToLiquidator,
    451
            debtToLiquidate: debtToLiquidate
    452
          });
    453
      }
    454
    455
      /// @notice Calculates the debt that should be liquidated.
    456
      /// @dev Generally, it returns the minimum of `debtToCover`, `debtReserveBalance` and `debtToTarget`.
    457
      /// If debt dust would be left behind, it returns `debtReserveBalance` to ensure the debt is fully cleared and no dust is left.
    458
      function _calculateDebtToLiquidate(
    459
        CalculateDebtToLiquidateParams memory params
    460
      ) internal pure returns (uint256) {
    461
        uint256 debtToLiquidate = params.debtReserveBalance;
    462
        if (params.debtToCover < debtToLiquidate) {
    463
          debtToLiquidate = params.debtToCover;
    464
        }
    465
    466
        uint256 debtToTarget = _calculateDebtToTargetHealthFactor(
    467
          CalculateDebtToTargetHealthFactorParams({
    468
            totalDebtValue: params.totalDebtValue,
    469
            debtAssetUnit: params.debtAssetUnit,
    470
            debtAssetPrice: params.debtAssetPrice,
    471
            collateralFactor: params.collateralFactor,
    472
            liquidationBonus: params.liquidationBonus,
    473
            healthFactor: params.healthFactor,
    474
            targetHealthFactor: params.targetHealthFactor
    475
          })
    476
        );
    477
        if (debtToTarget < debtToLiquidate) {
    478
          debtToLiquidate = debtToTarget;
    479
        }
    480
    481
        bool leavesDebtDust = debtToLiquidate < params.debtReserveBalance &&
    482
          (params.debtReserveBalance - debtToLiquidate).mulDivDown(
    483
            params.debtAssetPrice.toWad(),
    484
            params.debtAssetUnit
    485
          ) <
    486
          DUST_LIQUIDATION_THRESHOLD;
    487
    488
        if (leavesDebtDust) {
    489
          // target health factor is bypassed to prevent leaving dust
    490
          debtToLiquidate = params.debtReserveBalance;
    491
        }
    492
    493
        return debtToLiquidate;
    494
      }
    495
    496
      /// @notice Calculates the amount of debt needed to be liquidated to restore a position to the target health factor.
    497
      function _calculateDebtToTargetHealthFactor(
    498
        CalculateDebtToTargetHealthFactorParams memory params
    499
      ) internal pure returns (uint256) {
    500
        uint256 liquidationPenalty = params.liquidationBonus.bpsToWad().percentMulUp(
    501
          params.collateralFactor
    502
        );
    503
    504
        // denominator cannot be zero as `liquidationPenalty` is always < PercentageMath.PERCENTAGE_FACTOR
    505
        // `liquidationBonus.percentMulUp(collateralFactor) < PercentageMath.PERCENTAGE_FACTOR` is enforced in `_validateDynamicReserveConfig`
    506
        // and targetHealthFactor is always >= HEALTH_FACTOR_LIQUIDATION_THRESHOLD
    507
        return
    508
          params.totalDebtValue.mulDivUp(
    509
            params.debtAssetUnit * (params.targetHealthFactor - params.healthFactor),
    510
            (params.targetHealthFactor - liquidationPenalty) * params.debtAssetPrice.toWad()
    511
          );
    512
      }
    513
    514
      /// @notice Returns if the liquidation results in deficit.
    515
      function _evaluateDeficit(
    516
        bool isCollateralPositionEmpty,
    517
        bool isDebtPositionEmpty,
    518
        uint256 activeCollateralCount,
    519
        uint256 borrowedCount
    520
      ) internal pure returns (bool) {
    521
        if (!isCollateralPositionEmpty || activeCollateralCount > 1) {
    522
          return false;
    523
        }
    524
        return !isDebtPositionEmpty || borrowedCount > 1;
    525
      }
    526
    }
    527
    66.0% src/spoke/libraries/PositionStatusMap.sol
    Lines covered: 47 / 71 (66.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.20;
    4
    5
    import {LibBit} from 'src/dependencies/solady/LibBit.sol';
    6
    import {ISpoke} from 'src/spoke/interfaces/ISpoke.sol';
    7
    8
    /// @title PositionStatusMap Library
    9
    /// @author Aave Labs
    10
    /// @notice Implements the bitmap logic to handle the user configuration.
    11
    library PositionStatusMap {
    12
      using PositionStatusMap for *;
    13
      using LibBit for uint256;
    14
    15
      uint256 internal constant NOT_FOUND = type(uint256).max;
    16
    17
      uint256 internal constant BORROWING_MASK =
    18
        0x5555555555555555555555555555555555555555555555555555555555555555;
    19
      uint256 internal constant COLLATERAL_MASK =
    20
        0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA;
    21
    22
      /// @notice Sets if the user is borrowing the specified reserve.
    23
      function setBorrowing(
    24
        ISpoke.PositionStatus storage self,
    25
        uint256 reserveId,
    26
        bool borrowing
    27
      ) internal {
    28
        unchecked {
    29
          uint256 bit = 1 << ((reserveId % 128) << 1);
    30
          if (borrowing) {
    31
            self.map[reserveId.bucketId()] |= bit;
    32
          } else {
    33
            self.map[reserveId.bucketId()] &= ~bit;
    34
          }
    35
        }
    36
      }
    37
    38
      /// @notice Sets if the user is using as collateral the specified reserve.
    39
      function setUsingAsCollateral(
    40
        ISpoke.PositionStatus storage self,
    41
        uint256 reserveId,
    42
        bool usingAsCollateral
    43
      ) internal {
    44
        unchecked {
    45
          uint256 bit = 1 << (((reserveId % 128) << 1) + 1);
    46
          if (usingAsCollateral) {
    47
            self.map[reserveId.bucketId()] |= bit;
    48
          } else {
    49
            self.map[reserveId.bucketId()] &= ~bit;
    50
          }
    51
        }
    52
      }
    53
    54
      /// @notice Returns if a user is using the specified reserve for borrowing or as collateral.
    55
      function isUsingAsCollateralOrBorrowing(
    56
        ISpoke.PositionStatus storage self,
    57
        uint256 reserveId
    58
      ) internal view returns (bool) {
    59
        unchecked {
    60
          return (self.getBucketWord(reserveId) >> ((reserveId % 128) << 1)) & 3 != 0;
    61
        }
    62
      }
    63
    64
      /// @notice Returns if a user is using the specified reserve for borrowing.
    65
      function isBorrowing(
    66
        ISpoke.PositionStatus storage self,
    67
        uint256 reserveId
    68
      ) internal view returns (bool) {
    69
        unchecked {
    70
          return (self.getBucketWord(reserveId) >> ((reserveId % 128) << 1)) & 1 != 0;
    71
        }
    72
      }
    73
    74
      /// @notice Returns if a user is using the specified reserve as collateral.
    75
      function isUsingAsCollateral(
    76
        ISpoke.PositionStatus storage self,
    77
        uint256 reserveId
    78
      ) internal view returns (bool) {
    79
        unchecked {
    80
          return (self.getBucketWord(reserveId) >> (((reserveId % 128) << 1) + 1)) & 1 != 0;
    81
        }
    82
      }
    83
    84
      /// @notice Counts the number of reserves enabled as collateral.
    85
      /// @dev Disregards potential dirty bits set after `reserveCount`.
    86
      /// @param reserveCount The current `reserveCount`, to avoid reading uninitialized buckets.
    87
      function collateralCount(
    88
        ISpoke.PositionStatus storage self,
    89
        uint256 reserveCount
    90
      ) internal view returns (uint256) {
    91
        unchecked {
    92
          uint256 bucket = reserveCount.bucketId();
    93
          uint256 count = self.map[bucket].isolateCollateralUntil(reserveCount).popCount();
    94
          while (bucket != 0) {
    95
            count += self.map[--bucket].isolateCollateral().popCount();
    96
          }
    97
          return count;
    98
        }
    99
      }
    100
    101
      /// @notice Finds the previous borrowing or collateralized reserve strictly before `fromReserveId`.
    102
      /// @dev The search starts at `fromReserveId` (exclusive) and scans backward across buckets.
    103
      /// @dev Returns `NOT_FOUND` if no borrowing or collateralized reserve exists before the bound.
    104
      /// @dev Ignores dirty bits beyond the configured `reserveCount` within the last bucket.
    105
      /// @param fromReserveId The identifier of the reserve to start searching from.
    106
      /// @return reserveId The reserve identifier for the next reserve that is borrowed or used as collateral.
    107
      /// @return borrowing True if the next reserveId is borrowed.
    108
      /// @return collateral True if the next reserveId is used as collateral.
    109
      function next(
    110
        ISpoke.PositionStatus storage self,
    111
        uint256 fromReserveId
    112
      ) internal view returns (uint256, bool, bool) {
    113
        unchecked {
    114
          uint256 bucket = fromReserveId.bucketId();
    115
          uint256 map = self.map[bucket];
    116
          uint256 setBitId = map.isolateUntil(fromReserveId).fls();
    117
          while (setBitId == 256 && bucket != 0) {
    118
            map = self.map[--bucket];
    119
            setBitId = map.fls();
    120
          }
    121
          if (setBitId == 256) {
    122
            return (NOT_FOUND, false, false);
    123
          } else {
    124
            uint256 word = map >> ((setBitId >> 1) << 1);
    125
            return (setBitId.fromBitId(bucket), word & 1 != 0, word & 2 != 0);
    126
          }
    127
        }
    128
      }
    129
    130
      /// @notice Finds the previous borrowed reserve strictly before `fromReserveId`.
    131
      /// @dev The search starts at `fromReserveId` (exclusive) and scans backward across buckets.
    132
      /// @dev Returns `NOT_FOUND` if no borrowed reserve exists before the bound.
    133
      /// @dev Ignores dirty bits beyond the configured `reserveCount` within the last bucket.
    134
      /// @param fromReserveId The exclusive upper bound to start from (this reserveId is not considered).
    135
      /// @return The previous borrowed reserveId, or `NOT_FOUND` if none is found.
    136
      function nextBorrowing(
    137
        ISpoke.PositionStatus storage self,
    138
        uint256 fromReserveId
    139
      ) internal view returns (uint256) {
    140
        unchecked {
    141
          uint256 bucket = fromReserveId.bucketId();
    142
          uint256 setBitId = self.map[bucket].isolateBorrowingUntil(fromReserveId).fls();
    143
          while (setBitId == 256 && bucket != 0) {
    144
            setBitId = self.map[--bucket].isolateBorrowing().fls();
    145
          }
    146
          return setBitId == 256 ? NOT_FOUND : setBitId.fromBitId(bucket);
    147
        }
    148
      }
    149
    150
      /// @notice Finds the previous collateral reserve strictly before `fromReserveId`.
    151
      /// @dev The search starts at `fromReserveId` (exclusive) and scans backward across buckets.
    152
      /// @dev Returns `NOT_FOUND` if no collateral reserve exists before the bound.
    153
      /// @dev Ignores dirty bits beyond the configured `reserveCount` within the last bucket.
    154
      /// @param fromReserveId The exclusive upper bound to start from (this reserveId is not considered).
    155
      /// @return The previous collateral reserveId, or `NOT_FOUND` if none is found.
    156
      function nextCollateral(
    157
        ISpoke.PositionStatus storage self,
    158
        uint256 fromReserveId
    159
      ) internal view returns (uint256) {
    160
        unchecked {
    161
          uint256 bucket = fromReserveId.bucketId();
    162
          uint256 setBitId = self.map[bucket].isolateCollateralUntil(fromReserveId).fls();
    163
          while (setBitId == 256 && bucket != 0) {
    164
            setBitId = self.map[--bucket].isolateCollateral().fls();
    165
          }
    166
          return setBitId == 256 ? NOT_FOUND : setBitId.fromBitId(bucket);
    167
        }
    168
      }
    169
    170
      /// @notice Returns the word containing the reserve state in the bitmap.
    171
      function getBucketWord(
    172
        ISpoke.PositionStatus storage self,
    173
        uint256 reserveId
    174
      ) internal view returns (uint256) {
    175
        return self.map[reserveId.bucketId()];
    176
      }
    177
    178
      /// @notice Converts a reserveId to its corresponding bucketId.
    179
      function bucketId(uint256 reserveId) internal pure returns (uint256 wordId) {
    180
        assembly ('memory-safe') {
    181
          wordId := shr(7, reserveId)
    182
        }
    183
      }
    184
    185
      /// @notice Converts a bit index to its corresponding reserve index in the bitmap.
    186
      /// @dev BitId 0, 1 correspond to reserveId 0; BitId 2, 3 correspond to reserveId 1; etc.
    187
      function fromBitId(uint256 bitId, uint256 bucket) internal pure returns (uint256 reserveId) {
    188
        assembly ('memory-safe') {
    189
          reserveId := add(shr(1, bitId), shl(7, bucket))
    190
        }
    191
      }
    192
    193
      /// @notice Isolates the borrowing bits from word.
    194
      function isolateBorrowing(uint256 word) internal pure returns (uint256 ret) {
    195
        assembly ('memory-safe') {
    196
          ret := and(word, BORROWING_MASK)
    197
        }
    198
      }
    199
    200
      /// @notice Returns masked `word` containing only borrowing bits from the first reserve up to `reserveCount`.
    201
      function isolateBorrowingUntil(
    202
        uint256 word,
    203
        uint256 reserveCount
    204
      ) internal pure returns (uint256 ret) {
    205
        // ret = word & (BORROWING_MASK >> (256 - ((reserveCount % 128) << 1)));
    206
        assembly ('memory-safe') {
    207
          ret := and(word, shr(sub(256, shl(1, mod(reserveCount, 128))), BORROWING_MASK))
    208
        }
    209
      }
    210
    211
      /// @notice Returns masked `word` containing bits from the first reserve up to `reserveCount`.
    212
      function isolateUntil(uint256 word, uint256 reserveCount) internal pure returns (uint256 ret) {
    213
        // ret = word & (type(uint256).max >> (256 - ((reserveCount % 128) << 1)));
    214
        assembly ('memory-safe') {
    215
          ret := and(word, shr(sub(256, shl(1, mod(reserveCount, 128))), not(0)))
    216
        }
    217
      }
    218
    219
      /// @notice Isolates the collateral bits from word.
    220
      function isolateCollateral(uint256 word) internal pure returns (uint256 ret) {
    221
        assembly ('memory-safe') {
    222
          ret := and(word, COLLATERAL_MASK)
    223
        }
    224
      }
    225
    226
      /// @notice Returns masked `word` containing only collateral bits from the first reserve up to `reserveCount`.
    227
      function isolateCollateralUntil(
    228
        uint256 word,
    229
        uint256 reserveCount
    230
      ) internal pure returns (uint256 ret) {
    231
        // ret = word & (COLLATERAL_MASK >> (256 - ((reserveCount % 128) << 1)));
    232
        assembly ('memory-safe') {
    233
          ret := and(word, shr(sub(256, shl(1, mod(reserveCount, 128))), COLLATERAL_MASK))
    234
        }
    235
      }
    236
    }
    237
    100.0% src/spoke/libraries/ReserveFlagsMap.sol
    Lines covered: 20 / 20 (100.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.20;
    4
    5
    import {ReserveFlags} from 'src/spoke/interfaces/ISpoke.sol';
    6
    7
    /// @title ReserveFlags Library
    8
    /// @author Aave Labs
    9
    /// @notice Implements the bitmap logic to handle the Reserve flags configuration.
    10
    library ReserveFlagsMap {
    11
      /// @dev Mask for the `paused` flag.
    12
      uint8 internal constant PAUSED_MASK = 0x01;
    13
      /// @dev Mask for the `frozen` flag.
    14
      uint8 internal constant FROZEN_MASK = 0x02;
    15
      /// @dev Mask for the `borrowable` flag.
    16
      uint8 internal constant BORROWABLE_MASK = 0x04;
    17
      /// @dev Mask for the `liquidatable` flag.
    18
      uint8 internal constant LIQUIDATABLE_MASK = 0x08;
    19
      /// @dev Mask for the `receiveSharesEnabled` flag.
    20
      uint8 internal constant RECEIVE_SHARES_ENABLED_MASK = 0x10;
    21
    22
      /// @notice Initializes the ReserveFlags with the given values.
    23
      /// @param initPaused The initial `paused` flag status.
    24
      /// @param initFrozen The initial `frozen` flag status.
    25
      /// @param initBorrowable The initial `borrowable` flag status.
    26
      /// @param initLiquidatable The initial `liquidatable` flag status.
    27
      /// @param initReceiveSharesEnabled The initial `receiveSharesEnabled` flag status.
    28
      /// @return The initialized ReserveFlags.
    29
      function create(
    30
        bool initPaused,
    31
        bool initFrozen,
    32
        bool initBorrowable,
    33
        bool initLiquidatable,
    34
        bool initReceiveSharesEnabled
    35
      ) internal pure returns (ReserveFlags) {
    36
        uint8 flags = 0;
    37
        flags = _setStatus(flags, PAUSED_MASK, initPaused);
    38
        flags = _setStatus(flags, FROZEN_MASK, initFrozen);
    39
        flags = _setStatus(flags, BORROWABLE_MASK, initBorrowable);
    40
        flags = _setStatus(flags, LIQUIDATABLE_MASK, initLiquidatable);
    41
        flags = _setStatus(flags, RECEIVE_SHARES_ENABLED_MASK, initReceiveSharesEnabled);
    42
        return ReserveFlags.wrap(flags);
    43
      }
    44
    45
      /// @notice Sets the new status for the `paused` flag.
    46
      /// @param flags The current ReserveFlags.
    47
      /// @param status The new status for the `paused` flag.
    48
      /// @return The updated ReserveFlags.
    49
      function setPaused(ReserveFlags flags, bool status) internal pure returns (ReserveFlags) {
    50
        return ReserveFlags.wrap(_setStatus(ReserveFlags.unwrap(flags), PAUSED_MASK, status));
    51
      }
    52
    53
      /// @notice Sets the new status for the `frozen` flag.
    54
      /// @param flags The current ReserveFlags.
    55
      /// @param status The new status for the `frozen` flag.
    56
      /// @return The updated ReserveFlags.
    57
      function setFrozen(ReserveFlags flags, bool status) internal pure returns (ReserveFlags) {
    58
        return ReserveFlags.wrap(_setStatus(ReserveFlags.unwrap(flags), FROZEN_MASK, status));
    59
      }
    60
    61
      /// @notice Sets the new status for the `borrowable` flag.
    62
      /// @param flags The current ReserveFlags.
    63
      /// @param status The new status for the `borrowable` flag.
    64
      /// @return The updated ReserveFlags.
    65
      function setBorrowable(ReserveFlags flags, bool status) internal pure returns (ReserveFlags) {
    66
        return ReserveFlags.wrap(_setStatus(ReserveFlags.unwrap(flags), BORROWABLE_MASK, status));
    67
      }
    68
    69
      /// @notice Sets the new status for the `liquidatable` flag.
    70
      /// @param flags The current ReserveFlags.
    71
      /// @param status The new status for the `liquidatable` flag.
    72
      /// @return The updated ReserveFlags.
    73
      function setLiquidatable(ReserveFlags flags, bool status) internal pure returns (ReserveFlags) {
    74
        return ReserveFlags.wrap(_setStatus(ReserveFlags.unwrap(flags), LIQUIDATABLE_MASK, status));
    75
      }
    76
    77
      /// @notice Sets the new status for the `receiveSharesEnabled` flag.
    78
      /// @param flags The current ReserveFlags.
    79
      /// @param status The new status for the `receiveSharesEnabled` flag.
    80
      /// @return The updated ReserveFlags.
    81
      function setReceiveSharesEnabled(
    82
        ReserveFlags flags,
    83
        bool status
    84
      ) internal pure returns (ReserveFlags) {
    85
        return
    86
          ReserveFlags.wrap(
    87
            _setStatus(ReserveFlags.unwrap(flags), RECEIVE_SHARES_ENABLED_MASK, status)
    88
          );
    89
      }
    90
    91
      /// @notice Returns the `paused` flag status.
    92
      /// @param flags The current ReserveFlags.
    93
      /// @return True if the flag is set.
    94
      function paused(ReserveFlags flags) internal pure returns (bool) {
    95
        return (ReserveFlags.unwrap(flags) & PAUSED_MASK) != 0;
    96
      }
    97
    98
      /// @notice Returns the `frozen` flag status.
    99
      /// @param flags The current ReserveFlags.
    100
      /// @return True if the flag is set.
    101
      function frozen(ReserveFlags flags) internal pure returns (bool) {
    102
        return (ReserveFlags.unwrap(flags) & FROZEN_MASK) != 0;
    103
      }
    104
    105
      /// @notice Returns the `borrowable` flag status.
    106
      /// @param flags The current ReserveFlags.
    107
      /// @return True if the flag is set.
    108
      function borrowable(ReserveFlags flags) internal pure returns (bool) {
    109
        return (ReserveFlags.unwrap(flags) & BORROWABLE_MASK) != 0;
    110
      }
    111
    112
      /// @notice Returns the `liquidatable` flag status.
    113
      /// @param flags The current ReserveFlags.
    114
      /// @return True if the flag is set.
    115
      function liquidatable(ReserveFlags flags) internal pure returns (bool) {
    116
        return (ReserveFlags.unwrap(flags) & LIQUIDATABLE_MASK) != 0;
    117
      }
    118
    119
      /// @notice Returns the `receiveSharesEnabled` flag status.
    120
      /// @param flags The current ReserveFlags.
    121
      /// @return True if the flag is set.
    122
      function receiveSharesEnabled(ReserveFlags flags) internal pure returns (bool) {
    123
        return (ReserveFlags.unwrap(flags) & RECEIVE_SHARES_ENABLED_MASK) != 0;
    124
      }
    125
    126
      /// @notice Sets the new status for the given flag.
    127
      function _setStatus(uint8 flags, uint8 mask, bool status) private pure returns (uint8) {
    128
        return status ? flags | mask : flags & ~mask;
    129
      }
    130
    }
    131
    100.0% src/spoke/libraries/UserPositionDebt.sol
    Lines covered: 42 / 42 (100.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.20;
    4
    5
    import {SafeCast} from 'src/dependencies/openzeppelin/SafeCast.sol';
    6
    import {PercentageMath} from 'src/libraries/math/PercentageMath.sol';
    7
    import {WadRayMath} from 'src/libraries/math/WadRayMath.sol';
    8
    import {MathUtils} from 'src/libraries/math/MathUtils.sol';
    9
    import {Premium} from 'src/hub/libraries/Premium.sol';
    10
    import {IHubBase} from 'src/hub/interfaces/IHubBase.sol';
    11
    import {ISpoke} from 'src/spoke/interfaces/ISpoke.sol';
    12
    13
    /// @title User Debt library
    14
    /// @author Aave Labs
    15
    /// @notice Implements debt calculations for user positions.
    16
    library UserPositionDebt {
    17
      using UserPositionDebt for ISpoke.UserPosition;
    18
      using SafeCast for *;
    19
      using PercentageMath for uint256;
    20
      using WadRayMath for *;
    21
      using MathUtils for *;
    22
    23
      /// @notice Applies the premium delta to the user position.
    24
      /// @param userPosition The user position.
    25
      /// @param premiumDelta The premium delta to apply.
    26
      function applyPremiumDelta(
    27
        ISpoke.UserPosition storage userPosition,
    28
        IHubBase.PremiumDelta memory premiumDelta
    29
      ) internal {
    30
        userPosition.premiumShares = userPosition
    31
          .premiumShares
    32
          .add(premiumDelta.sharesDelta)
    33
          .toUint120();
    34
        userPosition.premiumOffsetRay = (userPosition.premiumOffsetRay + premiumDelta.offsetRayDelta)
    35
          .toInt200();
    36
      }
    37
    38
      /// @notice Calculates the premium delta for a user position given a new risk premium.
    39
      /// @param userPosition The user position.
    40
      /// @param drawnSharesTaken The amount of drawn shares taken from the user position.
    41
      /// @param drawnIndex The current drawn index.
    42
      /// @param riskPremium The new risk premium, expressed in BPS.
    43
      /// @param restoredPremiumRay The amount of premium to be restored, expressed in asset units and scaled by RAY.
    44
      /// @return The calculated premium delta.
    45
      function getPremiumDelta(
    46
        ISpoke.UserPosition storage userPosition,
    47
        uint256 drawnSharesTaken,
    48
        uint256 drawnIndex,
    49
        uint256 riskPremium,
    50
        uint256 restoredPremiumRay
    51
      ) internal view returns (IHubBase.PremiumDelta memory) {
    52
        uint256 oldPremiumShares = userPosition.premiumShares;
    53
        int256 oldPremiumOffsetRay = userPosition.premiumOffsetRay;
    54
        uint256 premiumDebtRay = Premium.calculatePremiumRay({
    55
          premiumShares: oldPremiumShares,
    56
          premiumOffsetRay: oldPremiumOffsetRay,
    57
          drawnIndex: drawnIndex
    58
        });
    59
        uint256 newPremiumShares = (userPosition.drawnShares - drawnSharesTaken).percentMulUp(
    60
          riskPremium
    61
        );
    62
        int256 newPremiumOffsetRay = (newPremiumShares * drawnIndex).signedSub(
    63
          premiumDebtRay - restoredPremiumRay
    64
        );
    65
    66
        return
    67
          IHubBase.PremiumDelta({
    68
            sharesDelta: newPremiumShares.signedSub(oldPremiumShares),
    69
            offsetRayDelta: newPremiumOffsetRay - oldPremiumOffsetRay,
    70
            restoredPremiumRay: restoredPremiumRay
    71
          });
    72
      }
    73
    74
      /// @dev Calculates the drawn debt and premium debt to restore for the given user position and amount.
    75
      /// @param userPosition The user position.
    76
      /// @param drawnIndex The drawn index of the reserve.
    77
      /// @param amount The amount to restore.
    78
      /// @return The amount of drawn debt to restore, expressed in asset units.
    79
      /// @return The amount of premium debt to restore, expressed in asset units and scaled by RAY.
    80
      function calculateRestoreAmount(
    81
        ISpoke.UserPosition storage userPosition,
    82
        uint256 drawnIndex,
    83
        uint256 amount
    84
      ) internal view returns (uint256, uint256) {
    85
        (uint256 drawnDebt, uint256 premiumDebtRay) = userPosition.getDebt(drawnIndex);
    86
        uint256 premiumDebt = premiumDebtRay.fromRayUp();
    87
        if (amount >= drawnDebt + premiumDebt) {
    88
          return (drawnDebt, premiumDebtRay);
    89
        }
    90
    91
        if (amount < premiumDebt) {
    92
          // amount.toRay() cannot overflow here
    93
          uint256 amountRay = amount.toRay();
    94
          return (0, amountRay);
    95
        }
    96
        return (amount - premiumDebt, premiumDebtRay);
    97
      }
    98
    99
      /// @return The user's drawn debt, expressed in asset units.
    100
      /// @return The user's premium debt, expressed in asset units and scaled by RAY.
    101
      function getDebt(
    102
        ISpoke.UserPosition storage userPosition,
    103
        IHubBase hub,
    104
        uint256 assetId
    105
      ) internal view returns (uint256, uint256) {
    106
        return userPosition.getDebt(hub.getAssetDrawnIndex(assetId));
    107
      }
    108
    109
      /// @return The user's drawn debt, expressed in asset units.
    110
      /// @return The user's premium debt, expressed in asset units and scaled by RAY.
    111
      function getDebt(
    112
        ISpoke.UserPosition storage userPosition,
    113
        uint256 drawnIndex
    114
      ) internal view returns (uint256, uint256) {
    115
        uint256 premiumDebtRay = _calculatePremiumRay(userPosition, drawnIndex);
    116
        return (userPosition.drawnShares.rayMulUp(drawnIndex), premiumDebtRay);
    117
      }
    118
    119
      /// @dev Calculates the premium debt of a user position with full precision.
    120
      /// @param userPosition The user position.
    121
      /// @param drawnIndex The current drawn index.
    122
      /// @return The premium debt, expressed in asset units and scaled by RAY.
    123
      function _calculatePremiumRay(
    124
        ISpoke.UserPosition storage userPosition,
    125
        uint256 drawnIndex
    126
      ) internal view returns (uint256) {
    127
        return
    128
          Premium.calculatePremiumRay({
    129
            premiumShares: userPosition.premiumShares,
    130
            premiumOffsetRay: userPosition.premiumOffsetRay,
    131
            drawnIndex: drawnIndex
    132
          });
    133
      }
    134
    }
    135
    0.0% src/utils/Multicall.sol
    Lines covered: 0 / 8 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.20;
    4
    5
    import {IMulticall} from 'src/interfaces/IMulticall.sol';
    6
    7
    /// @title Multicall
    8
    /// @author Aave Labs
    9
    /// @notice This contract allows for batching multiple calls into a single call.
    10
    /// @dev Inspired by the OpenZeppelin Multicall contract.
    11
    abstract contract Multicall is IMulticall {
    12
      /// @inheritdoc IMulticall
    13
      function multicall(bytes[] calldata data) external returns (bytes[] memory) {
    14
        bytes[] memory results = new bytes[](data.length);
    15
        for (uint256 i; i < data.length; ++i) {
    16
          (bool ok, bytes memory res) = address(this).delegatecall(data[i]);
    17
    18
          assembly ('memory-safe') {
    19
            if iszero(ok) {
    20
              revert(add(res, 32), mload(res)) // bubble up first revert
    21
            }
    22
          }
    23
    24
          results[i] = res;
    25
        }
    26
        return results;
    27
      }
    28
    }
    29
    0.0% src/utils/NoncesKeyed.sol
    Lines covered: 0 / 14 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.20;
    4
    5
    import {INoncesKeyed} from 'src/interfaces/INoncesKeyed.sol';
    6
    7
    /// @notice Provides tracking nonces for addresses. Supports key-ed nonces, where nonces will only increment for each key.
    8
    /// @author Modified from OpenZeppelin https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v5.2.0/contracts/utils/NoncesKeyed.sol
    9
    /// @dev Follows the https://eips.ethereum.org/EIPS/eip-4337#semi-abstracted-nonce-support[ERC-4337's semi-abstracted nonce system].
    10
    contract NoncesKeyed is INoncesKeyed {
    11
      mapping(address owner => mapping(uint192 key => uint64 nonce)) private _nonces;
    12
    13
      /// @inheritdoc INoncesKeyed
    14
      function useNonce(uint192 key) external returns (uint256) {
    15
        return _useNonce(msg.sender, key);
    16
      }
    17
    18
      /// @inheritdoc INoncesKeyed
    19
      function nonces(address owner, uint192 key) external view returns (uint256) {
    20
        return _pack(key, _nonces[owner][key]);
    21
      }
    22
    23
      /// @notice Consumes the next unused nonce for an address and key.
    24
      /// @dev Returns the current packed `keyNonce`. Consumed nonce is increased, so calling this function twice
    25
      /// with the same arguments will return different (sequential) results.
    26
      function _useNonce(address owner, uint192 key) internal returns (uint256) {
    27
        // For each account, the nonce has an initial value of 0, can only be incremented by one, and cannot be
    28
        // decremented or reset. This guarantees that the nonce never overflows.
    29
        unchecked {
    30
          // It is important to do x++ and not ++x here.
    31
          return _pack(key, _nonces[owner][key]++);
    32
        }
    33
      }
    34
    35
      /// @dev Same as `_useNonce` but checking that `nonce` is the next valid for `owner` for specified packed `keyNonce`.
    36
      function _useCheckedNonce(address owner, uint256 keyNonce) internal {
    37
        (uint192 key, ) = _unpack(keyNonce);
    38
        uint256 current = _useNonce(owner, key);
    39
        require(keyNonce == current, InvalidAccountNonce(owner, current));
    40
      }
    41
    42
      /// @dev Pack key and nonce into a keyNonce.
    43
      function _pack(uint192 key, uint64 nonce) private pure returns (uint256) {
    44
        return (uint256(key) << 64) | nonce;
    45
      }
    46
    47
      /// @dev Unpack a keyNonce into its key and nonce components.
    48
      function _unpack(uint256 keyNonce) private pure returns (uint192 key, uint64 nonce) {
    49
        return (uint192(keyNonce >> 64), uint64(keyNonce));
    50
      }
    51
    }
    52
    0.0% src/utils/Rescuable.sol
    Lines covered: 0 / 9 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.20;
    4
    5
    import {SafeERC20, IERC20} from 'src/dependencies/openzeppelin/SafeERC20.sol';
    6
    import {Address} from 'src/dependencies/openzeppelin/Address.sol';
    7
    import {IRescuable} from 'src/interfaces/IRescuable.sol';
    8
    9
    /// @title Rescuable
    10
    /// @author Aave Labs
    11
    /// @notice Contract that allows for the rescue of tokens and native assets.
    12
    abstract contract Rescuable is IRescuable {
    13
      using SafeERC20 for IERC20;
    14
    15
      modifier onlyRescueGuardian() {
    16
        _checkRescueGuardian();
    17
        _;
    18
      }
    19
    20
      /// @inheritdoc IRescuable
    21
      function rescueToken(address token, address to, uint256 amount) external onlyRescueGuardian {
    22
        IERC20(token).safeTransfer(to, amount);
    23
      }
    24
    25
      /// @inheritdoc IRescuable
    26
      function rescueNative(address to, uint256 amount) external onlyRescueGuardian {
    27
        Address.sendValue(payable(to), amount);
    28
      }
    29
    30
      /// @inheritdoc IRescuable
    31
      function rescueGuardian() external view returns (address) {
    32
        return _rescueGuardian();
    33
      }
    34
    35
      function _rescueGuardian() internal view virtual returns (address);
    36
    37
      function _checkRescueGuardian() internal view virtual {
    38
        require(_rescueGuardian() == msg.sender, OnlyRescueGuardian());
    39
      }
    40
    }
    41
    99.0% tests/Base.t.sol
    Lines covered: 436 / 438 (99.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    import {Test} from 'forge-std/Test.sol';
    6
    import {stdError} from 'forge-std/StdError.sol';
    7
    import {stdMath} from 'forge-std/StdMath.sol';
    8
    import {StdStorage, stdStorage} from 'forge-std/StdStorage.sol';
    9
    import {Vm, VmSafe} from 'forge-std/Vm.sol';
    10
    import {console2 as console} from 'forge-std/console2.sol';
    11
    12
    // dependencies
    13
    import {AggregatorV3Interface} from 'src/dependencies/chainlink/AggregatorV3Interface.sol';
    14
    import {TransparentUpgradeableProxy, ITransparentUpgradeableProxy} from 'src/dependencies/openzeppelin/TransparentUpgradeableProxy.sol';
    15
    import {IERC20Metadata} from 'src/dependencies/openzeppelin/IERC20Metadata.sol';
    16
    import {SafeCast} from 'src/dependencies/openzeppelin/SafeCast.sol';
    17
    import {IERC20Errors} from 'src/dependencies/openzeppelin/IERC20Errors.sol';
    18
    import {IERC20} from 'src/dependencies/openzeppelin/IERC20.sol';
    19
    import {IERC5267} from 'src/dependencies/openzeppelin/IERC5267.sol';
    20
    import {AccessManager} from 'src/dependencies/openzeppelin/AccessManager.sol';
    21
    import {IAccessManager} from 'src/dependencies/openzeppelin/IAccessManager.sol';
    22
    import {IAccessManaged} from 'src/dependencies/openzeppelin/IAccessManaged.sol';
    23
    import {AuthorityUtils} from 'src/dependencies/openzeppelin/AuthorityUtils.sol';
    24
    import {Ownable2Step, Ownable} from 'src/dependencies/openzeppelin/Ownable2Step.sol';
    25
    import {Math} from 'src/dependencies/openzeppelin/Math.sol';
    26
    import {WETH9} from 'src/dependencies/weth/WETH9.sol';
    27
    import {LibBit} from 'src/dependencies/solady/LibBit.sol';
    28
    29
    import {Initializable} from 'src/dependencies/openzeppelin-upgradeable/Initializable.sol';
    30
    import {IERC1967} from 'src/dependencies/openzeppelin/IERC1967.sol';
    31
    32
    // shared
    33
    import {WadRayMath} from 'src/libraries/math/WadRayMath.sol';
    34
    import {MathUtils} from 'src/libraries/math/MathUtils.sol';
    35
    import {PercentageMath} from 'src/libraries/math/PercentageMath.sol';
    36
    import {EIP712Types} from 'src/libraries/types/EIP712Types.sol';
    37
    import {Roles} from 'src/libraries/types/Roles.sol';
    38
    import {Rescuable, IRescuable} from 'src/utils/Rescuable.sol';
    39
    import {NoncesKeyed, INoncesKeyed} from 'src/utils/NoncesKeyed.sol';
    40
    import {UnitPriceFeed} from 'src/misc/UnitPriceFeed.sol';
    41
    import {AccessManagerEnumerable} from 'src/access/AccessManagerEnumerable.sol';
    42
    43
    // hub
    44
    import {HubConfigurator, IHubConfigurator} from 'src/hub/HubConfigurator.sol';
    45
    import {Hub, IHub, IHubBase} from 'src/hub/Hub.sol';
    46
    import {SharesMath} from 'src/hub/libraries/SharesMath.sol';
    47
    import {AssetInterestRateStrategy, IAssetInterestRateStrategy, IBasicInterestRateStrategy} from 'src/hub/AssetInterestRateStrategy.sol';
    48
    49
    // spoke
    50
    import {Spoke, ISpoke, ISpokeBase} from 'src/spoke/Spoke.sol';
    51
    import {TreasurySpoke, ITreasurySpoke} from 'src/spoke/TreasurySpoke.sol';
    52
    import {IPriceOracle} from 'src/spoke/interfaces/IPriceOracle.sol';
    53
    import {AaveOracle} from 'src/spoke/AaveOracle.sol';
    54
    import {IAaveOracle} from 'src/spoke/interfaces/IAaveOracle.sol';
    55
    import {SpokeConfigurator, ISpokeConfigurator} from 'src/spoke/SpokeConfigurator.sol';
    56
    import {SpokeInstance} from 'src/spoke/instances/SpokeInstance.sol';
    57
    import {PositionStatusMap} from 'src/spoke/libraries/PositionStatusMap.sol';
    58
    import {ReserveFlags, ReserveFlagsMap} from 'src/spoke/libraries/ReserveFlagsMap.sol';
    59
    import {LiquidationLogic} from 'src/spoke/libraries/LiquidationLogic.sol';
    60
    import {KeyValueList} from 'src/spoke/libraries/KeyValueList.sol';
    61
    62
    // position manager
    63
    import {GatewayBase, IGatewayBase} from 'src/position-manager/GatewayBase.sol';
    64
    import {NativeTokenGateway, INativeTokenGateway} from 'src/position-manager/NativeTokenGateway.sol';
    65
    import {SignatureGateway, ISignatureGateway} from 'src/position-manager/SignatureGateway.sol';
    66
    67
    // test
    68
    import {Constants} from 'tests/Constants.sol';
    69
    import {Utils} from 'tests/Utils.sol';
    70
    71
    // mocks
    72
    import {TestnetERC20} from 'tests/mocks/TestnetERC20.sol';
    73
    import {MockERC20} from 'tests/mocks/MockERC20.sol';
    74
    import {MockPriceFeed} from 'tests/mocks/MockPriceFeed.sol';
    75
    import {PositionStatusMapWrapper} from 'tests/mocks/PositionStatusMapWrapper.sol';
    76
    import {RescuableWrapper} from 'tests/mocks/RescuableWrapper.sol';
    77
    import {GatewayBaseWrapper} from 'tests/mocks/GatewayBaseWrapper.sol';
    78
    import {MockNoncesKeyed} from 'tests/mocks/MockNoncesKeyed.sol';
    79
    import {MockSpoke} from 'tests/mocks/MockSpoke.sol';
    80
    import {MockERC1271Wallet} from 'tests/mocks/MockERC1271Wallet.sol';
    81
    import {MockSpokeInstance} from 'tests/mocks/MockSpokeInstance.sol';
    82
    import {MockSkimSpoke} from 'tests/mocks/MockSkimSpoke.sol';
    83
    84
    abstract contract Base is Test {
    85
      using stdStorage for StdStorage;
    86
      using WadRayMath for *;
    87
      using SharesMath for uint256;
    88
      using PercentageMath for uint256;
    89
      using SafeCast for *;
    90
      using MathUtils for uint256;
    91
      using ReserveFlagsMap for ReserveFlags;
    92
    93
      bytes32 internal constant ERC1967_ADMIN_SLOT =
    94
        0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
    95
      bytes32 internal constant IMPLEMENTATION_SLOT =
    96
        0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
    97
    98
      uint256 internal constant MAX_SUPPLY_AMOUNT = 1e30;
    99
      uint256 internal constant MIN_TOKEN_DECIMALS_SUPPORTED = 6;
    100
      uint256 internal constant MAX_TOKEN_DECIMALS_SUPPORTED = 18;
    101
      uint256 internal constant MAX_SUPPLY_ASSET_UNITS =
    102
        MAX_SUPPLY_AMOUNT / 10 ** MAX_TOKEN_DECIMALS_SUPPORTED;
    103
      uint256 internal MAX_SUPPLY_AMOUNT_USDX;
    104
      uint256 internal MAX_SUPPLY_AMOUNT_DAI;
    105
      uint256 internal MAX_SUPPLY_AMOUNT_WBTC;
    106
      uint256 internal MAX_SUPPLY_AMOUNT_WETH;
    107
      uint256 internal MAX_SUPPLY_AMOUNT_USDY;
    108
      uint256 internal MAX_SUPPLY_AMOUNT_USDZ;
    109
      uint256 internal constant MAX_SUPPLY_IN_BASE_CURRENCY = 1e39;
    110
      uint24 internal constant MIN_COLLATERAL_RISK_BPS = 1;
    111
      uint24 internal constant MAX_COLLATERAL_RISK_BPS = 1000_00;
    112
      uint256 internal constant MAX_BORROW_RATE = 1000_00; // matches AssetInterestRateStrategy
    113
      uint256 internal constant MIN_OPTIMAL_RATIO = 1_00; // 1.00% in BPS, matches AssetInterestRateStrategy
    114
      uint256 internal constant MAX_OPTIMAL_RATIO = 99_00; // 99.00% in BPS, matches AssetInterestRateStrategy
    115
      uint256 internal constant MAX_SKIP_TIME = 10_000 days;
    116
      uint32 internal constant MIN_LIQUIDATION_BONUS = uint32(PercentageMath.PERCENTAGE_FACTOR); // 100% == 0% bonus
    117
      uint32 internal constant MAX_LIQUIDATION_BONUS = 150_00; // 50% bonus
    118
      uint16 internal constant MAX_LIQUIDATION_BONUS_FACTOR = uint16(PercentageMath.PERCENTAGE_FACTOR); // 100%
    119
      uint16 internal constant MAX_LIQUIDATION_FEE = 100_00;
    120
      uint16 internal constant MIN_LIQUIDATION_FEE = 0;
    121
      uint128 internal constant HEALTH_FACTOR_LIQUIDATION_THRESHOLD = 1e18;
    122
      uint128 internal constant MIN_CLOSE_FACTOR = 1e18;
    123
      uint128 internal constant MAX_CLOSE_FACTOR = 2e18;
    124
      uint256 internal constant MAX_COLLATERAL_FACTOR = 100_00;
    125
      uint256 internal constant MAX_ASSET_PRICE = 1e8 * 1e8; // $100M per token
    126
      uint256 internal constant MAX_LIQUIDATION_PROTOCOL_FEE_PERCENTAGE =
    127
        PercentageMath.PERCENTAGE_FACTOR;
    128
      IHubBase.PremiumDelta internal ZERO_PREMIUM_DELTA = ZERO_PREMIUM_DELTA;
    129
    130
      IAaveOracle internal oracle1;
    131
      IAaveOracle internal oracle2;
    132
      IAaveOracle internal oracle3;
    133
      IHub internal hub1;
    134
      ITreasurySpoke internal treasurySpoke;
    135
      ISpoke internal spoke1;
    136
      ISpoke internal spoke2;
    137
      ISpoke internal spoke3;
    138
      AssetInterestRateStrategy internal irStrategy;
    139
      IAccessManager internal accessManager;
    140
    141
      address internal alice = makeAddr('alice');
    142
      address internal bob = makeAddr('bob');
    143
      address internal carol = makeAddr('carol');
    144
      address internal derl = makeAddr('derl');
    145
    146
      address internal ADMIN = makeAddr('ADMIN');
    147
      address internal HUB_ADMIN = makeAddr('HUB_ADMIN');
    148
      address internal SPOKE_ADMIN = makeAddr('SPOKE_ADMIN');
    149
      address internal USER_POSITION_UPDATER = makeAddr('USER_POSITION_UPDATER');
    150
      address internal TREASURY_ADMIN = makeAddr('TREASURY_ADMIN');
    151
      address internal LIQUIDATOR = makeAddr('LIQUIDATOR');
    152
      address internal POSITION_MANAGER = makeAddr('POSITION_MANAGER');
    153
    154
      TokenList internal tokenList;
    155
      uint256 internal wethAssetId = 0;
    156
      uint256 internal usdxAssetId = 1;
    157
      uint256 internal daiAssetId = 2;
    158
      uint256 internal wbtcAssetId = 3;
    159
      uint256 internal usdyAssetId = 4;
    160
      uint256 internal usdzAssetId = 5;
    161
    162
      uint256 internal mintAmount_WETH = MAX_SUPPLY_AMOUNT;
    163
      uint256 internal mintAmount_USDX = MAX_SUPPLY_AMOUNT;
    164
      uint256 internal mintAmount_DAI = MAX_SUPPLY_AMOUNT;
    165
      uint256 internal mintAmount_WBTC = MAX_SUPPLY_AMOUNT;
    166
      uint256 internal mintAmount_USDY = MAX_SUPPLY_AMOUNT;
    167
      uint256 internal mintAmount_USDZ = MAX_SUPPLY_AMOUNT;
    168
    169
      Decimals internal _decimals = Decimals({usdx: 6, usdy: 18, dai: 18, wbtc: 8, weth: 18, usdz: 18});
    170
    171
      bool internal deployed = false;
    172
    173
      struct Decimals {
    174
        uint8 usdx;
    175
        uint8 dai;
    176
        uint8 wbtc;
    177
        uint8 usdy;
    178
        uint8 weth;
    179
        uint8 usdz;
    180
      }
    181
    182
      struct TokenList {
    183
        WETH9 weth;
    184
        TestnetERC20 usdx;
    185
        TestnetERC20 dai;
    186
        TestnetERC20 wbtc;
    187
        TestnetERC20 usdy;
    188
        TestnetERC20 usdz;
    189
      }
    190
    191
      struct SpokeInfo {
    192
        ReserveInfo weth;
    193
        ReserveInfo wbtc;
    194
        ReserveInfo dai;
    195
        ReserveInfo usdx;
    196
        ReserveInfo usdy;
    197
        ReserveInfo usdz;
    198
        uint256 MAX_ALLOWED_ASSET_ID;
    199
      }
    200
    201
      struct ReserveInfo {
    202
        uint256 reserveId;
    203
        ISpoke.ReserveConfig reserveConfig;
    204
        ISpoke.DynamicReserveConfig dynReserveConfig;
    205
      }
    206
    207
      struct DrawnAccounting {
    208
        uint256 totalOwed;
    209
        uint256 drawn;
    210
        uint256 premium;
    211
      }
    212
    213
      // TODO: Seems this should be replaced with DrawnAccounting struct
    214
      struct Debts {
    215
        uint256 drawnDebt;
    216
        uint256 premiumDebt;
    217
        uint256 totalDebt;
    218
      }
    219
    220
      struct AssetPosition {
    221
        uint256 assetId;
    222
        uint256 addedShares;
    223
        uint256 addedAmount;
    224
        uint256 drawnShares;
    225
        uint256 drawn;
    226
        uint256 premiumShares;
    227
        int256 premiumOffsetRay;
    228
        uint256 premium;
    229
        uint40 lastUpdateTimestamp;
    230
        uint256 liquidity;
    231
        uint256 drawnIndex;
    232
        uint256 drawnRate;
    233
      }
    234
    235
      struct SpokePosition {
    236
        uint256 reserveId;
    237
        uint256 assetId;
    238
        uint256 addedShares;
    239
        uint256 addedAmount;
    240
        uint256 drawnShares;
    241
        uint256 drawn;
    242
        uint256 premiumShares;
    243
        int256 premiumOffsetRay;
    244
        uint256 premium;
    245
      }
    246
    247
      struct Reserve {
    248
        uint256 reserveId;
    249
        IHub hub;
    250
        uint16 assetId;
    251
        uint8 decimals;
    252
        uint24 dynamicConfigKey; // key of the last reserve config
    253
        bool paused;
    254
        bool frozen;
    255
        bool borrowable;
    256
        bool receiveSharesEnabled;
    257
        uint24 collateralRisk;
    258
      }
    259
    260
      mapping(ISpoke => SpokeInfo) internal spokeInfo;
    261
    262
      function setUp() public virtual {
    263
        deployFixtures();
    264
      }
    265
    266
      function _getProxyAdminAddress(address proxy) internal view returns (address) {
    267
        bytes32 slotData = vm.load(proxy, ERC1967_ADMIN_SLOT);
    268
        return address(uint160(uint256(slotData)));
    269
      }
    270
    271
      function _getImplementationAddress(address proxy) internal view returns (address) {
    272
        bytes32 slotData = vm.load(proxy, IMPLEMENTATION_SLOT);
    273
        return address(uint160(uint256(slotData)));
    274
      }
    275
    276
      function deployFixtures() internal virtual {
    277
        if (deployed) return;
    278
    279
        vm.startPrank(ADMIN);
    280
        accessManager = IAccessManager(address(new AccessManagerEnumerable(ADMIN)));
    281
        hub1 = new Hub(address(accessManager));
    282
        irStrategy = new AssetInterestRateStrategy(address(hub1));
    283
        (spoke1, oracle1) = _deploySpokeWithOracle(ADMIN, address(accessManager), 'Spoke 1 (USD)');
    284
        (spoke2, oracle2) = _deploySpokeWithOracle(ADMIN, address(accessManager), 'Spoke 2 (USD)');
    285
        (spoke3, oracle3) = _deploySpokeWithOracle(ADMIN, address(accessManager), 'Spoke 3 (USD)');
    286
        treasurySpoke = ITreasurySpoke(new TreasurySpoke(TREASURY_ADMIN, address(hub1)));
    287
        vm.stopPrank();
    288
    289
        vm.label(address(spoke1), 'spoke1');
    290
        vm.label(address(spoke2), 'spoke2');
    291
        vm.label(address(spoke3), 'spoke3');
    292
    293
        setUpRoles(hub1, spoke1, accessManager);
    294
        setUpRoles(hub1, spoke2, accessManager);
    295
        setUpRoles(hub1, spoke3, accessManager);
    296
    297
        deployed = true; 
    298
      }
    299
    300
      function setUpRoles(IHub targetHub, ISpoke spoke, IAccessManager manager) internal virtual {
    301
        vm.startPrank(ADMIN);
    302
        // Grant roles with 0 delay
    303
        manager.grantRole(Roles.HUB_ADMIN_ROLE, ADMIN, 0);
    304
        manager.grantRole(Roles.HUB_ADMIN_ROLE, HUB_ADMIN, 0);
    305
    306
        manager.grantRole(Roles.SPOKE_ADMIN_ROLE, ADMIN, 0);
    307
        manager.grantRole(Roles.SPOKE_ADMIN_ROLE, SPOKE_ADMIN, 0);
    308
    309
        manager.grantRole(Roles.USER_POSITION_UPDATER_ROLE, ADMIN, 0);
    310
        manager.grantRole(Roles.USER_POSITION_UPDATER_ROLE, SPOKE_ADMIN, 0);
    311
        manager.grantRole(Roles.USER_POSITION_UPDATER_ROLE, USER_POSITION_UPDATER, 0);
    312
    313
        // Grant responsibilities to roles
    314
        {
    315
          bytes4[] memory selectors = new bytes4[](7);
    316
          selectors[0] = ISpoke.updateLiquidationConfig.selector;
    317
          selectors[1] = ISpoke.addReserve.selector;
    318
          selectors[2] = ISpoke.updateReserveConfig.selector;
    319
          selectors[3] = ISpoke.updateDynamicReserveConfig.selector;
    320
          selectors[4] = ISpoke.addDynamicReserveConfig.selector;
    321
          selectors[5] = ISpoke.updatePositionManager.selector;
    322
          selectors[6] = ISpoke.updateReservePriceSource.selector;
    323
          manager.setTargetFunctionRole(address(spoke), selectors, Roles.SPOKE_ADMIN_ROLE);
    324
        }
    325
    326
        {
    327
          bytes4[] memory selectors = new bytes4[](2);
    328
          selectors[0] = ISpoke.updateUserDynamicConfig.selector;
    329
          selectors[1] = ISpoke.updateUserRiskPremium.selector;
    330
          manager.setTargetFunctionRole(address(spoke), selectors, Roles.USER_POSITION_UPDATER_ROLE);
    331
        }
    332
    333
        {
    334
          bytes4[] memory selectors = new bytes4[](6);
    335
          selectors[0] = IHub.addAsset.selector;
    336
          selectors[1] = IHub.updateAssetConfig.selector;
    337
          selectors[2] = IHub.addSpoke.selector;
    338
          selectors[3] = IHub.updateSpokeConfig.selector;
    339
          selectors[4] = IHub.setInterestRateData.selector;
    340
          selectors[5] = IHub.mintFeeShares.selector;
    341
          manager.setTargetFunctionRole(address(targetHub), selectors, Roles.HUB_ADMIN_ROLE);
    342
        }
    343
        vm.stopPrank();
    344
      }
    345
    346
      function initEnvironment() internal {
    347
        deployMintAndApproveTokenList();
    348
        configureTokenList();
    349
      }
    350
    351
      function deployMintAndApproveTokenList() internal {
    352
        tokenList = TokenList(
    353
          new WETH9(),
    354
          new TestnetERC20('USDX', 'USDX', _decimals.usdx),
    355
          new TestnetERC20('DAI', 'DAI', _decimals.dai),
    356
          new TestnetERC20('WBTC', 'WBTC', _decimals.wbtc),
    357
          new TestnetERC20('USDY', 'USDY', _decimals.usdy),
    358
          new TestnetERC20('USDZ', 'USDZ', _decimals.usdz)
    359
        );
    360
    361
        vm.label(address(tokenList.weth), 'WETH');
    362
        vm.label(address(tokenList.usdx), 'USDX');
    363
        vm.label(address(tokenList.dai), 'DAI');
    364
        vm.label(address(tokenList.wbtc), 'WBTC');
    365
        vm.label(address(tokenList.usdy), 'USDY');
    366
    367
        MAX_SUPPLY_AMOUNT_USDX = MAX_SUPPLY_ASSET_UNITS * 10 ** tokenList.usdx.decimals();
    368
        MAX_SUPPLY_AMOUNT_WETH = MAX_SUPPLY_ASSET_UNITS * 10 ** tokenList.weth.decimals();
    369
        MAX_SUPPLY_AMOUNT_DAI = MAX_SUPPLY_ASSET_UNITS * 10 ** tokenList.dai.decimals();
    370
        MAX_SUPPLY_AMOUNT_WBTC = MAX_SUPPLY_ASSET_UNITS * 10 ** tokenList.wbtc.decimals();
    371
        MAX_SUPPLY_AMOUNT_USDY = MAX_SUPPLY_ASSET_UNITS * 10 ** tokenList.usdy.decimals();
    372
        MAX_SUPPLY_AMOUNT_USDZ = MAX_SUPPLY_ASSET_UNITS * 10 ** tokenList.usdz.decimals();
    373
    374
        address[7] memory users = [
    375
          alice,
    376
          bob,
    377
          carol,
    378
          derl,
    379
          LIQUIDATOR,
    380
          TREASURY_ADMIN,
    381
          POSITION_MANAGER
    382
        ];
    383
    384
        address[4] memory spokes = [
    385
          address(spoke1),
    386
          address(spoke2),
    387
          address(spoke3),
    388
          address(treasurySpoke)
    389
        ];
    390
    391
        for (uint256 x; x < users.length; ++x) {
    392
          tokenList.usdx.mint(users[x], mintAmount_USDX);
    393
          tokenList.dai.mint(users[x], mintAmount_DAI);
    394
          tokenList.wbtc.mint(users[x], mintAmount_WBTC);
    395
          tokenList.usdy.mint(users[x], mintAmount_USDY);
    396
          tokenList.usdz.mint(users[x], mintAmount_USDZ);
    397
          // deal(address(tokenList.weth), users[x], mintAmount_WETH);
    398
          vm.deal(address(this), mintAmount_WETH);
    399
          tokenList.weth.deposit{value: mintAmount_WETH}();
    400
          tokenList.weth.transfer(users[x], mintAmount_WETH);
    401
    402
          vm.startPrank(users[x]);
    403
          for (uint256 y; y < spokes.length; ++y) {
    404
            tokenList.weth.approve(spokes[y], UINT256_MAX);
    405
            tokenList.usdx.approve(spokes[y], UINT256_MAX);
    406
            tokenList.dai.approve(spokes[y], UINT256_MAX);
    407
            tokenList.wbtc.approve(spokes[y], UINT256_MAX);
    408
            tokenList.usdy.approve(spokes[y], UINT256_MAX);
    409
            tokenList.usdz.approve(spokes[y], UINT256_MAX);
    410
          }
    411
          vm.stopPrank();
    412
        }
    413
      }
    414
    415
      function spokeMintAndApprove() internal {
    416
        uint256 spokeMintAmount_USDX = 100e6 * 10 ** tokenList.usdx.decimals();
    417
        uint256 spokeMintAmount_DAI = 1e60;
    418
        uint256 spokeMintAmount_WBTC = 100e6 * 10 ** tokenList.wbtc.decimals();
    419
        uint256 spokeMintAmount_WETH = 100e6 * 10 ** tokenList.weth.decimals();
    420
        uint256 spokeMintAmount_USDY = 100e6 * 10 ** tokenList.usdy.decimals();
    421
        uint256 spokeMintAmount_USDZ = 100e6 * 10 ** tokenList.usdz.decimals();
    422
        address[3] memory spokes = [address(spoke1), address(spoke2), address(spoke3)];
    423
    424
        for (uint256 x; x < spokes.length; ++x) {
    425
          tokenList.usdx.mint(spokes[x], spokeMintAmount_USDX);
    426
          tokenList.dai.mint(spokes[x], spokeMintAmount_DAI);
    427
          tokenList.wbtc.mint(spokes[x], spokeMintAmount_WBTC);
    428
          tokenList.usdy.mint(spokes[x], spokeMintAmount_USDY);
    429
          tokenList.usdz.mint(spokes[x], spokeMintAmount_USDZ);
    430
          deal(address(tokenList.weth), spokes[x], spokeMintAmount_WETH);
    431
    432
          vm.startPrank(spokes[x]);
    433
          tokenList.weth.approve(address(hub1), UINT256_MAX);
    434
          tokenList.usdx.approve(address(hub1), UINT256_MAX);
    435
          tokenList.dai.approve(address(hub1), UINT256_MAX);
    436
          tokenList.wbtc.approve(address(hub1), UINT256_MAX);
    437
          tokenList.usdy.approve(address(hub1), UINT256_MAX);
    438
          tokenList.usdz.approve(address(hub1), UINT256_MAX);
    439
          vm.stopPrank();
    440
        }
    441
      }
    442
    443
      function configureTokenList() internal {
    444
        IHub.SpokeConfig memory spokeConfig = IHub.SpokeConfig({
    445
          active: true,
    446
          paused: false,
    447
          addCap: Constants.MAX_ALLOWED_SPOKE_CAP,
    448
          drawCap: Constants.MAX_ALLOWED_SPOKE_CAP,
    449
          riskPremiumThreshold: Constants.MAX_ALLOWED_COLLATERAL_RISK
    450
        });
    451
    452
        bytes memory encodedIrData = abi.encode(
    453
          IAssetInterestRateStrategy.InterestRateData({
    454
            optimalUsageRatio: 90_00, // 90.00%
    455
            baseVariableBorrowRate: 5_00, // 5.00%
    456
            variableRateSlope1: 5_00, // 5.00%
    457
            variableRateSlope2: 5_00 // 5.00%
    458
          })
    459
        );
    460
    461
        // Add all assets to the Hub
    462
        vm.startPrank(ADMIN);
    463
        // add WETH
    464
        hub1.addAsset(
    465
          address(tokenList.weth),
    466
          tokenList.weth.decimals(),
    467
          address(treasurySpoke),
    468
          address(irStrategy),
    469
          encodedIrData
    470
        );
    471
        hub1.updateAssetConfig(
    472
          wethAssetId,
    473
          IHub.AssetConfig({
    474
            liquidityFee: 10_00,
    475
            feeReceiver: address(treasurySpoke),
    476
            irStrategy: address(irStrategy),
    477
            reinvestmentController: address(0)
    478
          }),
    479
          new bytes(0)
    480
        );
    481
        // add USDX
    482
        hub1.addAsset(
    483
          address(tokenList.usdx),
    484
          tokenList.usdx.decimals(),
    485
          address(treasurySpoke),
    486
          address(irStrategy),
    487
          encodedIrData
    488
        );
    489
        hub1.updateAssetConfig(
    490
          usdxAssetId,
    491
          IHub.AssetConfig({
    492
            liquidityFee: 5_00,
    493
            feeReceiver: address(treasurySpoke),
    494
            irStrategy: address(irStrategy),
    495
            reinvestmentController: address(0)
    496
          }),
    497
          new bytes(0)
    498
        );
    499
        // add DAI
    500
        hub1.addAsset(
    501
          address(tokenList.dai),
    502
          tokenList.dai.decimals(),
    503
          address(treasurySpoke),
    504
          address(irStrategy),
    505
          encodedIrData
    506
        );
    507
        hub1.updateAssetConfig(
    508
          daiAssetId,
    509
          IHub.AssetConfig({
    510
            liquidityFee: 5_00,
    511
            feeReceiver: address(treasurySpoke),
    512
            irStrategy: address(irStrategy),
    513
            reinvestmentController: address(0)
    514
          }),
    515
          new bytes(0)
    516
        );
    517
        // add WBTC
    518
        hub1.addAsset(
    519
          address(tokenList.wbtc),
    520
          tokenList.wbtc.decimals(),
    521
          address(treasurySpoke),
    522
          address(irStrategy),
    523
          encodedIrData
    524
        );
    525
        hub1.updateAssetConfig(
    526
          wbtcAssetId,
    527
          IHub.AssetConfig({
    528
            liquidityFee: 10_00,
    529
            feeReceiver: address(treasurySpoke),
    530
            irStrategy: address(irStrategy),
    531
            reinvestmentController: address(0)
    532
          }),
    533
          new bytes(0)
    534
        );
    535
        // add USDY
    536
        hub1.addAsset(
    537
          address(tokenList.usdy),
    538
          tokenList.usdy.decimals(),
    539
          address(treasurySpoke),
    540
          address(irStrategy),
    541
          encodedIrData
    542
        );
    543
        hub1.updateAssetConfig(
    544
          usdyAssetId,
    545
          IHub.AssetConfig({
    546
            liquidityFee: 10_00,
    547
            feeReceiver: address(treasurySpoke),
    548
            irStrategy: address(irStrategy),
    549
            reinvestmentController: address(0)
    550
          }),
    551
          new bytes(0)
    552
        );
    553
        // add USDZ
    554
        hub1.addAsset(
    555
          address(tokenList.usdz),
    556
          tokenList.usdz.decimals(),
    557
          address(treasurySpoke),
    558
          address(irStrategy),
    559
          encodedIrData
    560
        );
    561
        hub1.updateAssetConfig(
    562
          hub1.getAssetCount() - 1,
    563
          IHub.AssetConfig({
    564
            liquidityFee: 5_00,
    565
            feeReceiver: address(treasurySpoke),
    566
            irStrategy: address(irStrategy),
    567
            reinvestmentController: address(0)
    568
          }),
    569
          new bytes(0)
    570
        );
    571
    572
        // Liquidation configs
    573
        spoke1.updateLiquidationConfig(
    574
          ISpoke.LiquidationConfig({
    575
            targetHealthFactor: 1.05e18,
    576
            healthFactorForMaxBonus: 0.7e18,
    577
            liquidationBonusFactor: 20_00
    578
          })
    579
        );
    580
        spoke2.updateLiquidationConfig(
    581
          ISpoke.LiquidationConfig({
    582
            targetHealthFactor: 1.04e18,
    583
            healthFactorForMaxBonus: 0.8e18,
    584
            liquidationBonusFactor: 15_00
    585
          })
    586
        );
    587
        spoke3.updateLiquidationConfig(
    588
          ISpoke.LiquidationConfig({
    589
            targetHealthFactor: 1.03e18,
    590
            healthFactorForMaxBonus: 0.9e18,
    591
            liquidationBonusFactor: 10_00
    592
          })
    593
        );
    594
    595
        // Spoke 1 reserve configs
    596
        spokeInfo[spoke1].weth.reserveConfig = _getDefaultReserveConfig(15_00);
    597
        spokeInfo[spoke1].weth.dynReserveConfig = ISpoke.DynamicReserveConfig({
    598
          collateralFactor: 80_00,
    599
          maxLiquidationBonus: 105_00,
    600
          liquidationFee: 10_00
    601
        });
    602
        spokeInfo[spoke1].wbtc.reserveConfig = _getDefaultReserveConfig(15_00);
    603
        spokeInfo[spoke1].wbtc.dynReserveConfig = ISpoke.DynamicReserveConfig({
    604
          collateralFactor: 75_00,
    605
          maxLiquidationBonus: 103_00,
    606
          liquidationFee: 15_00
    607
        });
    608
        spokeInfo[spoke1].dai.reserveConfig = _getDefaultReserveConfig(20_00);
    609
        spokeInfo[spoke1].dai.dynReserveConfig = ISpoke.DynamicReserveConfig({
    610
          collateralFactor: 78_00,
    611
          maxLiquidationBonus: 102_00,
    612
          liquidationFee: 10_00
    613
        });
    614
        spokeInfo[spoke1].usdx.reserveConfig = _getDefaultReserveConfig(50_00);
    615
        spokeInfo[spoke1].usdx.dynReserveConfig = ISpoke.DynamicReserveConfig({
    616
          collateralFactor: 78_00,
    617
          maxLiquidationBonus: 101_00,
    618
          liquidationFee: 12_00
    619
        });
    620
        spokeInfo[spoke1].usdy.reserveConfig = _getDefaultReserveConfig(50_00);
    621
        spokeInfo[spoke1].usdy.dynReserveConfig = ISpoke.DynamicReserveConfig({
    622
          collateralFactor: 78_00,
    623
          maxLiquidationBonus: 101_50,
    624
          liquidationFee: 15_00
    625
        });
    626
    627
        spokeInfo[spoke1].weth.reserveId = spoke1.addReserve(
    628
          address(hub1),
    629
          wethAssetId,
    630
          _deployMockPriceFeed(spoke1, 2000e8),
    631
          spokeInfo[spoke1].weth.reserveConfig,
    632
          spokeInfo[spoke1].weth.dynReserveConfig
    633
        );
    634
        spokeInfo[spoke1].wbtc.reserveId = spoke1.addReserve(
    635
          address(hub1),
    636
          wbtcAssetId,
    637
          _deployMockPriceFeed(spoke1, 50_000e8),
    638
          spokeInfo[spoke1].wbtc.reserveConfig,
    639
          spokeInfo[spoke1].wbtc.dynReserveConfig
    640
        );
    641
        spokeInfo[spoke1].dai.reserveId = spoke1.addReserve(
    642
          address(hub1),
    643
          daiAssetId,
    644
          _deployMockPriceFeed(spoke1, 1e8),
    645
          spokeInfo[spoke1].dai.reserveConfig,
    646
          spokeInfo[spoke1].dai.dynReserveConfig
    647
        );
    648
        spokeInfo[spoke1].usdx.reserveId = spoke1.addReserve(
    649
          address(hub1),
    650
          usdxAssetId,
    651
          _deployMockPriceFeed(spoke1, 1e8),
    652
          spokeInfo[spoke1].usdx.reserveConfig,
    653
          spokeInfo[spoke1].usdx.dynReserveConfig
    654
        );
    655
        spokeInfo[spoke1].usdy.reserveId = spoke1.addReserve(
    656
          address(hub1),
    657
          usdyAssetId,
    658
          _deployMockPriceFeed(spoke1, 1e8),
    659
          spokeInfo[spoke1].usdy.reserveConfig,
    660
          spokeInfo[spoke1].usdy.dynReserveConfig
    661
        );
    662
    663
        hub1.addSpoke(wethAssetId, address(spoke1), spokeConfig);
    664
        hub1.addSpoke(wbtcAssetId, address(spoke1), spokeConfig);
    665
        hub1.addSpoke(daiAssetId, address(spoke1), spokeConfig);
    666
        hub1.addSpoke(usdxAssetId, address(spoke1), spokeConfig);
    667
        hub1.addSpoke(usdyAssetId, address(spoke1), spokeConfig);
    668
    669
        // Spoke 2 reserve configs
    670
        spokeInfo[spoke2].wbtc.reserveConfig = _getDefaultReserveConfig(0);
    671
        spokeInfo[spoke2].wbtc.dynReserveConfig = ISpoke.DynamicReserveConfig({
    672
          collateralFactor: 80_00,
    673
          maxLiquidationBonus: 105_00,
    674
          liquidationFee: 10_00
    675
        });
    676
        spokeInfo[spoke2].weth.reserveConfig = _getDefaultReserveConfig(10_00);
    677
        spokeInfo[spoke2].weth.dynReserveConfig = ISpoke.DynamicReserveConfig({
    678
          collateralFactor: 76_00,
    679
          maxLiquidationBonus: 103_00,
    680
          liquidationFee: 15_00
    681
        });
    682
        spokeInfo[spoke2].dai.reserveConfig = _getDefaultReserveConfig(20_00);
    683
        spokeInfo[spoke2].dai.dynReserveConfig = ISpoke.DynamicReserveConfig({
    684
          collateralFactor: 72_00,
    685
          maxLiquidationBonus: 102_00,
    686
          liquidationFee: 10_00
    687
        });
    688
        spokeInfo[spoke2].usdx.reserveConfig = _getDefaultReserveConfig(50_00);
    689
        spokeInfo[spoke2].usdx.dynReserveConfig = ISpoke.DynamicReserveConfig({
    690
          collateralFactor: 72_00,
    691
          maxLiquidationBonus: 101_00,
    692
          liquidationFee: 12_00
    693
        });
    694
        spokeInfo[spoke2].usdy.reserveConfig = _getDefaultReserveConfig(50_00);
    695
        spokeInfo[spoke2].usdy.dynReserveConfig = ISpoke.DynamicReserveConfig({
    696
          collateralFactor: 72_00,
    697
          maxLiquidationBonus: 101_50,
    698
          liquidationFee: 15_00
    699
        });
    700
        spokeInfo[spoke2].usdz.reserveConfig = _getDefaultReserveConfig(100_00);
    701
        spokeInfo[spoke2].usdz.dynReserveConfig = ISpoke.DynamicReserveConfig({
    702
          collateralFactor: 70_00,
    703
          maxLiquidationBonus: 106_00,
    704
          liquidationFee: 10_00
    705
        });
    706
    707
        spokeInfo[spoke2].wbtc.reserveId = spoke2.addReserve(
    708
          address(hub1),
    709
          wbtcAssetId,
    710
          _deployMockPriceFeed(spoke2, 50_000e8),
    711
          spokeInfo[spoke2].wbtc.reserveConfig,
    712
          spokeInfo[spoke2].wbtc.dynReserveConfig
    713
        );
    714
        spokeInfo[spoke2].weth.reserveId = spoke2.addReserve(
    715
          address(hub1),
    716
          wethAssetId,
    717
          _deployMockPriceFeed(spoke2, 2000e8),
    718
          spokeInfo[spoke2].weth.reserveConfig,
    719
          spokeInfo[spoke2].weth.dynReserveConfig
    720
        );
    721
        spokeInfo[spoke2].dai.reserveId = spoke2.addReserve(
    722
          address(hub1),
    723
          daiAssetId,
    724
          _deployMockPriceFeed(spoke2, 1e8),
    725
          spokeInfo[spoke2].dai.reserveConfig,
    726
          spokeInfo[spoke2].dai.dynReserveConfig
    727
        );
    728
        spokeInfo[spoke2].usdx.reserveId = spoke2.addReserve(
    729
          address(hub1),
    730
          usdxAssetId,
    731
          _deployMockPriceFeed(spoke2, 1e8),
    732
          spokeInfo[spoke2].usdx.reserveConfig,
    733
          spokeInfo[spoke2].usdx.dynReserveConfig
    734
        );
    735
        spokeInfo[spoke2].usdy.reserveId = spoke2.addReserve(
    736
          address(hub1),
    737
          usdyAssetId,
    738
          _deployMockPriceFeed(spoke2, 1e8),
    739
          spokeInfo[spoke2].usdy.reserveConfig,
    740
          spokeInfo[spoke2].usdy.dynReserveConfig
    741
        );
    742
        spokeInfo[spoke2].usdz.reserveId = spoke2.addReserve(
    743
          address(hub1),
    744
          usdzAssetId,
    745
          _deployMockPriceFeed(spoke2, 1e8),
    746
          spokeInfo[spoke2].usdz.reserveConfig,
    747
          spokeInfo[spoke2].usdz.dynReserveConfig
    748
        );
    749
    750
        hub1.addSpoke(wbtcAssetId, address(spoke2), spokeConfig);
    751
        hub1.addSpoke(wethAssetId, address(spoke2), spokeConfig);
    752
        hub1.addSpoke(daiAssetId, address(spoke2), spokeConfig);
    753
        hub1.addSpoke(usdxAssetId, address(spoke2), spokeConfig);
    754
        hub1.addSpoke(usdyAssetId, address(spoke2), spokeConfig);
    755
        hub1.addSpoke(usdzAssetId, address(spoke2), spokeConfig);
    756
    757
        // Spoke 3 reserve configs
    758
        spokeInfo[spoke3].dai.reserveConfig = _getDefaultReserveConfig(0);
    759
        spokeInfo[spoke3].dai.dynReserveConfig = ISpoke.DynamicReserveConfig({
    760
          collateralFactor: 75_00,
    761
          maxLiquidationBonus: 104_00,
    762
          liquidationFee: 11_00
    763
        });
    764
        spokeInfo[spoke3].usdx.reserveConfig = _getDefaultReserveConfig(10_00);
    765
        spokeInfo[spoke3].usdx.dynReserveConfig = ISpoke.DynamicReserveConfig({
    766
          collateralFactor: 75_00,
    767
          maxLiquidationBonus: 103_00,
    768
          liquidationFee: 15_00
    769
        });
    770
        spokeInfo[spoke3].weth.reserveConfig = _getDefaultReserveConfig(20_00);
    771
        spokeInfo[spoke3].weth.dynReserveConfig = ISpoke.DynamicReserveConfig({
    772
          collateralFactor: 79_00,
    773
          maxLiquidationBonus: 102_00,
    774
          liquidationFee: 10_00
    775
        });
    776
        spokeInfo[spoke3].wbtc.reserveConfig = _getDefaultReserveConfig(50_00);
    777
        spokeInfo[spoke3].wbtc.dynReserveConfig = ISpoke.DynamicReserveConfig({
    778
          collateralFactor: 77_00,
    779
          maxLiquidationBonus: 101_00,
    780
          liquidationFee: 12_00
    781
        });
    782
    783
        spokeInfo[spoke3].dai.reserveId = spoke3.addReserve(
    784
          address(hub1),
    785
          daiAssetId,
    786
          _deployMockPriceFeed(spoke3, 1e8),
    787
          spokeInfo[spoke3].dai.reserveConfig,
    788
          spokeInfo[spoke3].dai.dynReserveConfig
    789
        );
    790
        spokeInfo[spoke3].usdx.reserveId = spoke3.addReserve(
    791
          address(hub1),
    792
          usdxAssetId,
    793
          _deployMockPriceFeed(spoke3, 1e8),
    794
          spokeInfo[spoke3].usdx.reserveConfig,
    795
          spokeInfo[spoke3].usdx.dynReserveConfig
    796
        );
    797
        spokeInfo[spoke3].weth.reserveId = spoke3.addReserve(
    798
          address(hub1),
    799
          wethAssetId,
    800
          _deployMockPriceFeed(spoke3, 2000e8),
    801
          spokeInfo[spoke3].weth.reserveConfig,
    802
          spokeInfo[spoke3].weth.dynReserveConfig
    803
        );
    804
        spokeInfo[spoke3].wbtc.reserveId = spoke3.addReserve(
    805
          address(hub1),
    806
          wbtcAssetId,
    807
          _deployMockPriceFeed(spoke3, 50_000e8),
    808
          spokeInfo[spoke3].wbtc.reserveConfig,
    809
          spokeInfo[spoke3].wbtc.dynReserveConfig
    810
        );
    811
    812
        hub1.addSpoke(daiAssetId, address(spoke3), spokeConfig);
    813
        hub1.addSpoke(usdxAssetId, address(spoke3), spokeConfig);
    814
        hub1.addSpoke(wethAssetId, address(spoke3), spokeConfig);
    815
        hub1.addSpoke(wbtcAssetId, address(spoke3), spokeConfig);
    816
    817
        vm.stopPrank();
    818
      }
    819
    820
      /* @dev Configures Hub 2 with the following assetIds:
    821
       * 0: WETH
    822
       * 1: USDX
    823
       * 2: DAI
    824
       * 3: WBTC
    825
       */
    826
      function hub2Fixture() internal returns (IHub, AssetInterestRateStrategy) {
    827
        IAccessManager accessManager2 = IAccessManager(address(new AccessManagerEnumerable(ADMIN)));
    828
        IHub hub2 = new Hub(address(accessManager2));
    829
        vm.label(address(hub2), 'Hub2');
    830
        AssetInterestRateStrategy hub2IrStrategy = new AssetInterestRateStrategy(address(hub2));
    831
    832
        // Configure IR Strategy for hub 2
    833
        bytes memory encodedIrData = abi.encode(
    834
          IAssetInterestRateStrategy.InterestRateData({
    835
            optimalUsageRatio: 90_00, // 90.00%
    836
            baseVariableBorrowRate: 5_00, // 5.00%
    837
            variableRateSlope1: 5_00, // 5.00%
    838
            variableRateSlope2: 5_00 // 5.00%
    839
          })
    840
        );
    841
    842
        vm.startPrank(ADMIN);
    843
    844
        // Add assets to the second hub
    845
        // Add WETH
    846
        hub2.addAsset(
    847
          address(tokenList.weth),
    848
          tokenList.weth.decimals(),
    849
          address(treasurySpoke),
    850
          address(hub2IrStrategy),
    851
          encodedIrData
    852
        );
    853
    854
        // Add USDX
    855
        hub2.addAsset(
    856
          address(tokenList.usdx),
    857
          tokenList.usdx.decimals(),
    858
          address(treasurySpoke),
    859
          address(hub2IrStrategy),
    860
          encodedIrData
    861
        );
    862
    863
        // Add DAI
    864
        hub2.addAsset(
    865
          address(tokenList.dai),
    866
          tokenList.dai.decimals(),
    867
          address(treasurySpoke),
    868
          address(hub2IrStrategy),
    869
          encodedIrData
    870
        );
    871
    872
        // Add WBTC
    873
        hub2.addAsset(
    874
          address(tokenList.wbtc),
    875
          tokenList.wbtc.decimals(),
    876
          address(treasurySpoke),
    877
          address(hub2IrStrategy),
    878
          encodedIrData
    879
        );
    880
        vm.stopPrank();
    881
    882
        setUpRoles(hub2, spoke1, accessManager2);
    883
    884
        return (hub2, hub2IrStrategy);
    885
      }
    886
    887
      /* @dev Configures Hub 3 with the following assetIds:
    888
       * 0: DAI
    889
       * 1: USDX
    890
       * 2: WBTC
    891
       * 3: WETH
    892
       */
    893
      function hub3Fixture() internal returns (IHub, AssetInterestRateStrategy) {
    894
        IAccessManager accessManager3 = IAccessManager(address(new AccessManagerEnumerable(ADMIN)));
    895
        IHub hub3 = new Hub(address(accessManager3));
    896
        AssetInterestRateStrategy hub3IrStrategy = new AssetInterestRateStrategy(address(hub3));
    897
    898
        // Configure IR Strategy for hub 3
    899
        bytes memory encodedIrData = abi.encode(
    900
          IAssetInterestRateStrategy.InterestRateData({
    901
            optimalUsageRatio: 90_00, // 90.00%
    902
            baseVariableBorrowRate: 5_00, // 5.00%
    903
            variableRateSlope1: 5_00, // 5.00%
    904
            variableRateSlope2: 5_00 // 5.00%
    905
          })
    906
        );
    907
    908
        vm.startPrank(ADMIN);
    909
        // Add DAI
    910
        hub3.addAsset(
    911
          address(tokenList.dai),
    912
          tokenList.dai.decimals(),
    913
          address(treasurySpoke),
    914
          address(hub3IrStrategy),
    915
          encodedIrData
    916
        );
    917
    918
        // Add USDX
    919
        hub3.addAsset(
    920
          address(tokenList.usdx),
    921
          tokenList.usdx.decimals(),
    922
          address(treasurySpoke),
    923
          address(hub3IrStrategy),
    924
          encodedIrData
    925
        );
    926
    927
        // Add WBTC
    928
        hub3.addAsset(
    929
          address(tokenList.wbtc),
    930
          tokenList.wbtc.decimals(),
    931
          address(treasurySpoke),
    932
          address(hub3IrStrategy),
    933
          encodedIrData
    934
        );
    935
    936
        // Add WETH
    937
        hub3.addAsset(
    938
          address(tokenList.weth),
    939
          tokenList.weth.decimals(),
    940
          address(treasurySpoke),
    941
          address(hub3IrStrategy),
    942
          encodedIrData
    943
        );
    944
    945
        vm.stopPrank();
    946
    947
        setUpRoles(hub3, spoke1, accessManager3);
    948
    949
        return (hub3, hub3IrStrategy);
    950
      }
    951
    952
      function updateAssetFeeReceiver(
    953
        IHub hub,
    954
        uint256 assetId,
    955
        address newFeeReceiver
    956
      ) internal pausePrank {
    957
        IHub.AssetConfig memory config = hub.getAssetConfig(assetId);
    958
        config.feeReceiver = newFeeReceiver;
    959
    960
        vm.prank(HUB_ADMIN);
    961
        hub.updateAssetConfig(assetId, config, new bytes(0));
    962
    963
        assertEq(hub.getAssetConfig(assetId), config);
    964
      }
    965
    966
      function updateAssetReinvestmentController(
    967
        IHub hub,
    968
        uint256 assetId,
    969
        address newReinvestmentController
    970
      ) internal pausePrank {
    971
        IHub.AssetConfig memory config = hub.getAssetConfig(assetId);
    972
        config.reinvestmentController = newReinvestmentController;
    973
    974
        vm.prank(HUB_ADMIN);
    975
        hub.updateAssetConfig(assetId, config, new bytes(0));
    976
    977
        assertEq(hub.getAssetConfig(assetId), config);
    978
      }
    979
    980
      function updateReserveFrozenFlag(
    981
        ISpoke spoke,
    982
        uint256 reserveId,
    983
        bool newFrozenFlag
    984
      ) internal pausePrank {
    985
        ISpoke.ReserveConfig memory config = spoke.getReserveConfig(reserveId);
    986
        config.frozen = newFrozenFlag;
    987
    988
        vm.prank(SPOKE_ADMIN);
    989
        spoke.updateReserveConfig(reserveId, config);
    990
    991
        assertEq(spoke.getReserveConfig(reserveId), config);
    992
      }
    993
    994
      function _updateReservePausedFlag(
    995
        ISpoke spoke,
    996
        uint256 reserveId,
    997
        bool paused
    998
      ) internal pausePrank {
    999
        ISpoke.ReserveConfig memory config = spoke.getReserveConfig(reserveId);
    1000
        config.paused = paused;
    1001
    1002
        vm.prank(SPOKE_ADMIN);
    1003
        spoke.updateReserveConfig(reserveId, config);
    1004
    1005
        assertEq(spoke.getReserveConfig(reserveId), config);
    1006
      }
    1007
    1008
      function _updateReserveReceiveSharesEnabledFlag(
    1009
        ISpoke spoke,
    1010
        uint256 reserveId,
    1011
        bool receiveSharesEnabled
    1012
      ) internal pausePrank {
    1013
        ISpoke.ReserveConfig memory config = spoke.getReserveConfig(reserveId);
    1014
        config.receiveSharesEnabled = receiveSharesEnabled;
    1015
    1016
        vm.prank(SPOKE_ADMIN);
    1017
        spoke.updateReserveConfig(reserveId, config);
    1018
    1019
        assertEq(spoke.getReserveConfig(reserveId), config);
    1020
      }
    1021
    1022
      function _updateLiquidationConfig(
    1023
        ISpoke spoke,
    1024
        ISpoke.LiquidationConfig memory config
    1025
      ) internal pausePrank {
    1026
        vm.prank(SPOKE_ADMIN);
    1027
        spoke.updateLiquidationConfig(config);
    1028
    1029
        assertEq(spoke.getLiquidationConfig(), config);
    1030
      }
    1031
    1032
      function _updateMaxLiquidationBonus(
    1033
        ISpoke spoke,
    1034
        uint256 reserveId,
    1035
        uint32 newMaxLiquidationBonus
    1036
      ) internal pausePrank returns (uint24) {
    1037
        ISpoke.DynamicReserveConfig memory config = _getLatestDynamicReserveConfig(spoke, reserveId);
    1038
        config.maxLiquidationBonus = newMaxLiquidationBonus;
    1039
    1040
        vm.prank(SPOKE_ADMIN);
    1041
        uint24 dynamicConfigKey = spoke.addDynamicReserveConfig(reserveId, config);
    1042
    1043
        assertEq(_getLatestDynamicReserveConfig(spoke, reserveId), config);
    1044
        return dynamicConfigKey;
    1045
      }
    1046
    1047
      function _updateLiquidationFee(
    1048
        ISpoke spoke,
    1049
        uint256 reserveId,
    1050
        uint16 newLiquidationFee
    1051
      ) internal pausePrank returns (uint24) {
    1052
        ISpoke.DynamicReserveConfig memory config = _getLatestDynamicReserveConfig(spoke, reserveId);
    1053
        config.liquidationFee = newLiquidationFee;
    1054
    1055
        vm.prank(SPOKE_ADMIN);
    1056
        uint24 dynamicConfigKey = spoke.addDynamicReserveConfig(reserveId, config);
    1057
    1058
        assertEq(_getLatestDynamicReserveConfig(spoke, reserveId), config);
    1059
        return dynamicConfigKey;
    1060
      }
    1061
    1062
      function _updateCollateralFactorAndLiquidationBonus(
    1063
        ISpoke spoke,
    1064
        uint256 reserveId,
    1065
        uint256 newCollateralFactor,
    1066
        uint256 newLiquidationBonus
    1067
      ) internal pausePrank returns (uint24) {
    1068
        ISpoke.DynamicReserveConfig memory config = _getLatestDynamicReserveConfig(spoke, reserveId);
    1069
        config.collateralFactor = newCollateralFactor.toUint16();
    1070
        config.maxLiquidationBonus = newLiquidationBonus.toUint32();
    1071
    1072
        vm.prank(SPOKE_ADMIN);
    1073
        uint24 dynamicConfigKey = spoke.addDynamicReserveConfig(reserveId, config);
    1074
    1075
        assertEq(_getLatestDynamicReserveConfig(spoke, reserveId), config);
    1076
        return dynamicConfigKey;
    1077
      }
    1078
    1079
      function _updateCollateralFactor(
    1080
        ISpoke spoke,
    1081
        uint256 reserveId,
    1082
        uint256 newCollateralFactor
    1083
      ) internal pausePrank returns (uint24) {
    1084
        ISpoke.DynamicReserveConfig memory config = _getLatestDynamicReserveConfig(spoke, reserveId);
    1085
        config.collateralFactor = newCollateralFactor.toUint16();
    1086
        vm.prank(SPOKE_ADMIN);
    1087
        uint24 dynamicConfigKey = spoke.addDynamicReserveConfig(reserveId, config);
    1088
    1089
        assertEq(_getLatestDynamicReserveConfig(spoke, reserveId), config);
    1090
        return dynamicConfigKey;
    1091
      }
    1092
    1093
      function _updateCollateralFactorAtKey(
    1094
        ISpoke spoke,
    1095
        uint256 reserveId,
    1096
        uint24 dynamicConfigKey,
    1097
        uint256 newCollateralFactor
    1098
      ) internal pausePrank {
    1099
        ISpoke.DynamicReserveConfig memory config = spoke.getDynamicReserveConfig(
    1100
          reserveId,
    1101
          dynamicConfigKey
    1102
        );
    1103
        config.collateralFactor = newCollateralFactor.toUint16();
    1104
        vm.prank(SPOKE_ADMIN);
    1105
        spoke.updateDynamicReserveConfig(reserveId, dynamicConfigKey, config);
    1106
    1107
        assertEq(_getLatestDynamicReserveConfig(spoke, reserveId), config);
    1108
      }
    1109
    1110
      function updateReserveBorrowableFlag(
    1111
        ISpoke spoke,
    1112
        uint256 reserveId,
    1113
        bool newBorrowable
    1114
      ) internal pausePrank {
    1115
        ISpoke.ReserveConfig memory config = spoke.getReserveConfig(reserveId);
    1116
        config.borrowable = newBorrowable;
    1117
        vm.prank(SPOKE_ADMIN);
    1118
        spoke.updateReserveConfig(reserveId, config);
    1119
    1120
        assertEq(spoke.getReserveConfig(reserveId), config);
    1121
      }
    1122
    1123
      function _updateCollateralRisk(
    1124
        ISpoke spoke,
    1125
        uint256 reserveId,
    1126
        uint24 newCollateralRisk
    1127
      ) internal pausePrank {
    1128
        ISpoke.ReserveConfig memory config = spoke.getReserveConfig(reserveId);
    1129
        config.collateralRisk = newCollateralRisk;
    1130
        vm.prank(SPOKE_ADMIN);
    1131
        spoke.updateReserveConfig(reserveId, config);
    1132
    1133
        assertEq(spoke.getReserveConfig(reserveId), config);
    1134
      }
    1135
    1136
      function updateLiquidityFee(IHub hub, uint256 assetId, uint256 liquidityFee) internal pausePrank {
    1137
        IHub.AssetConfig memory config = hub.getAssetConfig(assetId);
    1138
        config.liquidityFee = liquidityFee.toUint16();
    1139
        vm.prank(HUB_ADMIN);
    1140
        hub.updateAssetConfig(assetId, config, new bytes(0));
    1141
    1142
        assertEq(hub.getAssetConfig(assetId), config);
    1143
      }
    1144
    1145
      function _updateTargetHealthFactor(
    1146
        ISpoke spoke,
    1147
        uint128 newTargetHealthFactor
    1148
      ) internal pausePrank {
    1149
        ISpoke.LiquidationConfig memory liqConfig = spoke.getLiquidationConfig();
    1150
        liqConfig.targetHealthFactor = newTargetHealthFactor;
    1151
        vm.prank(SPOKE_ADMIN);
    1152
        spoke.updateLiquidationConfig(liqConfig);
    1153
    1154
        assertEq(spoke.getLiquidationConfig(), liqConfig);
    1155
      }
    1156
    1157
      function getTargetHealthFactor(ISpoke spoke) internal view returns (uint256) {
    1158
        ISpoke.LiquidationConfig memory liqConfig = spoke.getLiquidationConfig();
    1159
        return liqConfig.targetHealthFactor;
    1160
      }
    1161
    1162
      /// @dev pseudo random randomizer
    1163
      function randomizer(uint256 min, uint256 max) internal returns (uint256) {
    1164
        return vm.randomUint(min, max);
    1165
      }
    1166
    1167
      function _randomNonceKey() internal returns (uint192) {
    1168
        return uint192(vm.randomUint());
    1169
      }
    1170
    1171
      function _randomNonce() internal returns (uint64) {
    1172
        return uint64(vm.randomUint());
    1173
      }
    1174
    1175
      // assumes spoke has usdx supported
    1176
      function _usdxReserveId(ISpoke spoke) internal view returns (uint256) {
    1177
        return spokeInfo[spoke].usdx.reserveId;
    1178
      }
    1179
    1180
      // assumes spoke has usdy supported
    1181
      function _usdyReserveId(ISpoke spoke) internal view returns (uint256) {
    1182
        return spokeInfo[spoke].usdy.reserveId;
    1183
      }
    1184
    1185
      // assumes spoke has dai supported
    1186
      function _daiReserveId(ISpoke spoke) internal view returns (uint256) {
    1187
        return spokeInfo[spoke].dai.reserveId;
    1188
      }
    1189
    1190
      // assumes spoke has weth supported
    1191
      function _wethReserveId(ISpoke spoke) internal view returns (uint256) {
    1192
        return spokeInfo[spoke].weth.reserveId;
    1193
      }
    1194
    1195
      // assumes spoke has wbtc supported
    1196
      function _wbtcReserveId(ISpoke spoke) internal view returns (uint256) {
    1197
        return spokeInfo[spoke].wbtc.reserveId;
    1198
      }
    1199
    1200
      // assumes spoke has usdz supported
    1201
      function _usdzReserveId(ISpoke spoke) internal view returns (uint256) {
    1202
        return spokeInfo[spoke].usdz.reserveId;
    1203
      }
    1204
    1205
      function _updateSpokePaused(
    1206
        IHub hub,
    1207
        uint256 assetId,
    1208
        address spoke,
    1209
        bool paused
    1210
      ) internal pausePrank {
    1211
        IHub.SpokeConfig memory spokeConfig = hub.getSpokeConfig(assetId, spoke);
    1212
        spokeConfig.paused = paused;
    1213
        vm.prank(HUB_ADMIN);
    1214
        hub.updateSpokeConfig(assetId, spoke, spokeConfig);
    1215
    1216
        assertEq(hub.getSpokeConfig(assetId, spoke), spokeConfig);
    1217
      }
    1218
    1219
      function updateSpokeActive(
    1220
        IHub hub,
    1221
        uint256 assetId,
    1222
        address spoke,
    1223
        bool newActive
    1224
      ) internal pausePrank {
    1225
        IHub.SpokeConfig memory spokeConfig = hub.getSpokeConfig(assetId, spoke);
    1226
        spokeConfig.active = newActive;
    1227
        vm.prank(HUB_ADMIN);
    1228
        hub.updateSpokeConfig(assetId, spoke, spokeConfig);
    1229
    1230
        assertEq(hub.getSpokeConfig(assetId, spoke), spokeConfig);
    1231
      }
    1232
    1233
      function updateDrawCap(
    1234
        IHub hub,
    1235
        uint256 assetId,
    1236
        address spoke,
    1237
        uint40 newDrawCap
    1238
      ) internal pausePrank {
    1239
        IHub.SpokeConfig memory spokeConfig = hub.getSpokeConfig(assetId, spoke);
    1240
        spokeConfig.drawCap = newDrawCap;
    1241
        vm.prank(HUB_ADMIN);
    1242
        hub.updateSpokeConfig(assetId, spoke, spokeConfig);
    1243
    1244
        assertEq(hub.getSpokeConfig(assetId, spoke), spokeConfig);
    1245
      }
    1246
    1247
      function _updateSpokeRiskPremiumThreshold(
    1248
        IHub hub,
    1249
        uint256 assetId,
    1250
        address spoke,
    1251
        uint24 newRiskPremiumThreshold
    1252
      ) internal pausePrank {
    1253
        IHub.SpokeConfig memory spokeConfig = hub.getSpokeConfig(assetId, spoke);
    1254
        spokeConfig.riskPremiumThreshold = newRiskPremiumThreshold;
    1255
        vm.prank(HUB_ADMIN);
    1256
        hub.updateSpokeConfig(assetId, spoke, spokeConfig);
    1257
    1258
        assertEq(hub.getSpokeConfig(assetId, spoke), spokeConfig);
    1259
      }
    1260
    1261
      function getUserInfo(
    1262
        ISpoke spoke,
    1263
        address user,
    1264
        uint256 reserveId
    1265
      ) internal view returns (ISpoke.UserPosition memory) {
    1266
        return spoke.getUserPosition(reserveId, user);
    1267
      }
    1268
    1269
      function getUserDebt(
    1270
        ISpoke spoke,
    1271
        address user,
    1272
        uint256 reserveId
    1273
      ) internal view returns (Debts memory data) {
    1274
        (data.drawnDebt, data.premiumDebt) = spoke.getUserDebt(reserveId, user);
    1275
        data.totalDebt = data.drawnDebt + data.premiumDebt;
    1276
      }
    1277
    1278
      function _isUsingAsCollateral(
    1279
        ISpoke spoke,
    1280
        uint256 reserveId,
    1281
        address user
    1282
      ) internal view returns (bool) {
    1283
        (bool res, ) = spoke.getUserReserveStatus(reserveId, user);
    1284
        return res;
    1285
      }
    1286
    1287
      function _isBorrowing(
    1288
        ISpoke spoke,
    1289
        uint256 reserveId,
    1290
        address user
    1291
      ) internal view returns (bool) {
    1292
        (, bool res) = spoke.getUserReserveStatus(reserveId, user);
    1293
        return res;
    1294
      }
    1295
    1296
      function getReserveInfo(
    1297
        ISpoke spoke,
    1298
        uint256 reserveId
    1299
      ) internal view returns (ISpoke.Reserve memory) {
    1300
        return spoke.getReserve(reserveId);
    1301
      }
    1302
    1303
      function _getReserveLastDynamicConfigKey(
    1304
        ISpoke spoke,
    1305
        uint256 reserveId
    1306
      ) internal view returns (uint24) {
    1307
        return spoke.getReserve(reserveId).dynamicConfigKey;
    1308
      }
    1309
    1310
      function _getLatestDynamicReserveConfig(
    1311
        ISpoke spoke,
    1312
        uint256 reserveId
    1313
      ) internal view returns (ISpoke.DynamicReserveConfig memory) {
    1314
        return
    1315
          spoke.getDynamicReserveConfig(reserveId, _getReserveLastDynamicConfigKey(spoke, reserveId));
    1316
      }
    1317
    1318
      function getSpokeInfo(
    1319
        uint256 assetId,
    1320
        address spoke
    1321
      ) internal view returns (IHub.SpokeData memory) {
    1322
        return hub1.getSpoke(assetId, spoke);
    1323
      }
    1324
    1325
      function getAssetInfo(uint256 assetId) internal view returns (IHub.Asset memory) {
    1326
        return hub1.getAsset(assetId);
    1327
      }
    1328
    1329
      function getAssetByReserveId(
    1330
        ISpoke spoke,
    1331
        uint256 reserveId
    1332
      ) internal view returns (uint256, IERC20) {
    1333
        ISpoke.Reserve memory reserve = spoke.getReserve(reserveId);
    1334
        (address underlying, ) = reserve.hub.getAssetUnderlyingAndDecimals(reserve.assetId);
    1335
        return (reserve.assetId, IERC20(underlying));
    1336
      }
    1337
    1338
      function getAssetUnderlyingByReserveId(
    1339
        ISpoke spoke,
    1340
        uint256 reserveId
    1341
      ) internal view returns (IERC20) {
    1342
        ISpoke.Reserve memory reserve = spoke.getReserve(reserveId);
    1343
        (address underlying, ) = reserve.hub.getAssetUnderlyingAndDecimals(reserve.assetId);
    1344
        return IERC20(underlying);
    1345
      }
    1346
    1347
      function getTotalWithdrawable(
    1348
        ISpoke spoke,
    1349
        uint256 reserveId,
    1350
        address user
    1351
      ) internal view returns (uint256) {
    1352
        return spoke.getUserSuppliedAssets(reserveId, user);
    1353
      }
    1354
    1355
      /// @dev Helper function to calculate asset amount corresponding to single added share
    1356
      function minimumAssetsPerAddedShare(IHub hub, uint256 assetId) internal view returns (uint256) {
    1357
        return hub.previewAddByShares(assetId, 1);
    1358
      }
    1359
    1360
      /// @dev Helper function to calculate asset amount corresponding to single drawn share
    1361
      function minimumAssetsPerDrawnShare(IHub hub, uint256 assetId) internal view returns (uint256) {
    1362
        return hub.previewRestoreByShares(assetId, 1);
    1363
      }
    1364
    1365
      /// @dev Helper function to calculate expected supplied assets based on amount to supply and current exchange rate
    1366
      /// taking potential donation into account
    1367
      function calculateEffectiveAddedAssets(
    1368
        uint256 assetsAmount,
    1369
        uint256 totalAddedAssets,
    1370
        uint256 totalAddedShares
    1371
      ) internal pure returns (uint256) {
    1372
        uint256 sharesAmount = assetsAmount.toSharesDown(totalAddedAssets, totalAddedShares);
    1373
        return
    1374
          sharesAmount.toAssetsDown(totalAddedAssets + assetsAmount, totalAddedShares + sharesAmount);
    1375
      }
    1376
    1377
      function getAddExRate(uint256 assetId) internal view returns (uint256) {
    1378
        return hub1.previewRemoveByShares(assetId, MAX_SUPPLY_AMOUNT);
    1379
      }
    1380
    1381
      function getDebtExRate(uint256 assetId) internal view returns (uint256) {
    1382
        return hub1.previewRestoreByShares(assetId, MAX_SUPPLY_AMOUNT);
    1383
      }
    1384
    1385
      function getAssetDrawnRate(IHub hub, uint256 assetId) internal view returns (uint256) {
    1386
        return hub.getAsset(assetId).drawnRate;
    1387
      }
    1388
    1389
      /// @dev Helper function to ensure supply exchange rate is monotonically increasing
    1390
      function _checkSupplyRateIncreasing(
    1391
        uint256 oldRate,
    1392
        uint256 newRate,
    1393
        string memory label
    1394
      ) internal pure {
    1395
        assertGe(newRate, oldRate, string.concat('supply rate monotonically increasing ', label));
    1396
      }
    1397
    1398
      function _checkDebtRateConstant(
    1399
        uint256 oldRate,
    1400
        uint256 newRate,
    1401
        string memory label
    1402
      ) internal pure {
    1403
        assertEq(newRate, oldRate, string.concat('debt rate should be constant ', label));
    1404
      }
    1405
    1406
      /// returns the USD value of the reserve normalized by it's decimals, in terms of WAD
    1407
      function _getValue(
    1408
        ISpoke spoke,
    1409
        uint256 reserveId,
    1410
        uint256 amount
    1411
      ) internal view returns (uint256) {
    1412
        return
    1413
          (amount * IPriceOracle(spoke.ORACLE()).getReservePrice(reserveId)).wadDivDown(
    1414
            10 ** _underlying(spoke, reserveId).decimals()
    1415
          );
    1416
      }
    1417
    1418
      /// returns the USD value of the reserve normalized by it's decimals, in terms of WAD
    1419
      function _getDebtValue(
    1420
        ISpoke spoke,
    1421
        uint256 reserveId,
    1422
        uint256 amount
    1423
      ) internal view returns (uint256) {
    1424
        return
    1425
          (amount * IPriceOracle(spoke.ORACLE()).getReservePrice(reserveId)).wadDivUp(
    1426
            10 ** _underlying(spoke, reserveId).decimals()
    1427
          );
    1428
      }
    1429
    1430
      /// @notice Convert 1 asset amount to equivalent amount in another asset.
    1431
      /// @notice Will contain precision loss due to conversion split into two steps.
    1432
      /// @return Converted amount of toAsset.
    1433
      function _convertAssetAmount(
    1434
        ISpoke spoke,
    1435
        uint256 reserveId,
    1436
        uint256 amount,
    1437
        uint256 toReserveId
    1438
      ) internal view returns (uint256) {
    1439
        return
    1440
          _convertValueToAmount(spoke, toReserveId, _convertAmountToValue(spoke, reserveId, amount));
    1441
      }
    1442
    1443
      /// @dev Helper function to calculate the amount of base and premium debt to restore
    1444
      // @return drawnRestored amount of drawn debt to restore
    1445
      // @return premiumRestored amount of premium debt to restore
    1446
      function _calculateExactRestoreAmount(
    1447
        uint256 drawn,
    1448
        uint256 premium,
    1449
        uint256 restoreAmount,
    1450
        uint256 assetId
    1451
      ) internal view returns (uint256, uint256) {
    1452
        if (restoreAmount <= premium) {
    1453
          return (0, restoreAmount);
    1454
        }
    1455
        uint256 drawnRestored = _min(drawn, restoreAmount - premium);
    1456
        // round drawn debt to nearest whole share
    1457
        drawnRestored = hub1.previewRestoreByShares(
    1458
          assetId,
    1459
          hub1.previewRestoreByAssets(assetId, drawnRestored)
    1460
        );
    1461
        return (drawnRestored, premium);
    1462
      }
    1463
    1464
      function _calculateExactRestoreAmount(
    1465
        ISpoke spoke,
    1466
        uint256 reserveId,
    1467
        address user,
    1468
        uint256 repayAmount
    1469
      ) internal view returns (uint256 baseRestored, uint256 premiumRestored) {
    1470
        (uint256 userDrawnDebt, uint256 userPremiumDebt) = spoke.getUserDebt(reserveId, user);
    1471
        return
    1472
          _calculateExactRestoreAmount(
    1473
            userDrawnDebt,
    1474
            userPremiumDebt,
    1475
            repayAmount,
    1476
            _spokeAssetId(spoke, reserveId)
    1477
          );
    1478
      }
    1479
    1480
      function _calculateRestoreAmounts(
    1481
        uint256 restoreAmount,
    1482
        uint256 drawn,
    1483
        uint256 premium
    1484
      ) internal pure returns (uint256 baseAmount, uint256 premiumAmount) {
    1485
        if (restoreAmount <= premium) {
    1486
          return (0, restoreAmount);
    1487
        }
    1488
    1489
        return (drawn.min(restoreAmount - premium), premium);
    1490
      }
    1491
    1492
      function _calculateRestoreAmounts(
    1493
        ISpoke spoke,
    1494
        uint256 reserveId,
    1495
        address user,
    1496
        uint256 repayAmount
    1497
      ) internal view returns (uint256 baseAmount, uint256 premiumAmount) {
    1498
        (uint256 userDrawnDebt, uint256 userPremiumDebt) = spoke.getUserDebt(reserveId, user);
    1499
        return _calculateRestoreAmounts(repayAmount, userDrawnDebt, userPremiumDebt);
    1500
      }
    1501
    1502
      function _getExpectedPremiumDelta(
    1503
        uint256 drawnIndex,
    1504
        uint256 oldPremiumShares,
    1505
        int256 oldPremiumOffsetRay,
    1506
        uint256 drawnShares,
    1507
        uint256 riskPremium,
    1508
        uint256 restoredPremiumRay
    1509
      ) internal pure returns (IHubBase.PremiumDelta memory) {
    1510
        uint256 premiumDebtRay = _calculatePremiumDebtRay(
    1511
          oldPremiumShares,
    1512
          oldPremiumOffsetRay,
    1513
          drawnIndex
    1514
        );
    1515
    1516
        uint256 newPremiumShares = drawnShares.percentMulUp(riskPremium);
    1517
        int256 newPremiumOffsetRay = _calculatePremiumAssetsRay(newPremiumShares, drawnIndex).signedSub(
    1518
          premiumDebtRay - restoredPremiumRay
    1519
        );
    1520
    1521
        return
    1522
          IHubBase.PremiumDelta({
    1523
            sharesDelta: newPremiumShares.toInt256() - oldPremiumShares.toInt256(),
    1524
            offsetRayDelta: newPremiumOffsetRay - oldPremiumOffsetRay,
    1525
            restoredPremiumRay: restoredPremiumRay
    1526
          });
    1527
      }
    1528
    1529
      function _getExpectedPremiumDelta(
    1530
        IHub hub,
    1531
        uint256 assetId,
    1532
        uint256 oldPremiumShares,
    1533
        int256 oldPremiumOffsetRay,
    1534
        uint256 drawnShares,
    1535
        uint256 riskPremium,
    1536
        uint256 restoredPremiumRay
    1537
      ) internal view returns (IHubBase.PremiumDelta memory) {
    1538
        return
    1539
          _getExpectedPremiumDelta({
    1540
            drawnIndex: hub.getAssetDrawnIndex(assetId),
    1541
            oldPremiumShares: oldPremiumShares,
    1542
            oldPremiumOffsetRay: oldPremiumOffsetRay,
    1543
            drawnShares: drawnShares,
    1544
            riskPremium: riskPremium,
    1545
            restoredPremiumRay: restoredPremiumRay
    1546
          });
    1547
      }
    1548
    1549
      function _getExpectedPremiumDelta(
    1550
        ISpoke spoke,
    1551
        address user,
    1552
        uint256 reserveId,
    1553
        uint256 repayAmount
    1554
      ) internal view virtual returns (IHubBase.PremiumDelta memory) {
    1555
        Debts memory userDebt = getUserDebt(spoke, user, reserveId);
    1556
        (, uint256 premiumAmountToRestore) = _calculateRestoreAmounts(
    1557
          repayAmount,
    1558
          userDebt.drawnDebt,
    1559
          userDebt.premiumDebt
    1560
        );
    1561
    1562
        ISpoke.UserPosition memory userPosition = spoke.getUserPosition(reserveId, user);
    1563
        uint256 assetId = spoke.getReserve(reserveId).assetId;
    1564
        uint256 premiumDebtRay = _calculatePremiumDebtRay(
    1565
          hub1,
    1566
          assetId,
    1567
          userPosition.premiumShares,
    1568
          userPosition.premiumOffsetRay
    1569
        );
    1570
    1571
        uint256 restoredPremiumRay = (premiumAmountToRestore * WadRayMath.RAY).min(premiumDebtRay);
    1572
    1573
        return
    1574
          _getExpectedPremiumDelta({
    1575
            hub: hub1,
    1576
            assetId: assetId,
    1577
            oldPremiumShares: userPosition.premiumShares,
    1578
            oldPremiumOffsetRay: userPosition.premiumOffsetRay,
    1579
            drawnShares: 0, // risk premium is 0, so drawn shares do not matter here (otherwise they need to be updated with restored drawn shares amount)
    1580
            riskPremium: 0,
    1581
            restoredPremiumRay: restoredPremiumRay
    1582
          });
    1583
      }
    1584
    1585
      // in restore actions, premiumDelta is first reset to last user RP
    1586
      function _getExpectedPremiumDeltaForRestore(
    1587
        ISpoke spoke,
    1588
        address user,
    1589
        uint256 reserveId,
    1590
        uint256 repayAmount
    1591
      ) internal view virtual returns (IHubBase.PremiumDelta memory) {
    1592
        Debts memory userDebt = getUserDebt(spoke, user, reserveId);
    1593
        (uint256 drawnDebtToRestore, uint256 premiumAmountToRestore) = _calculateRestoreAmounts(
    1594
          repayAmount,
    1595
          userDebt.drawnDebt,
    1596
          userDebt.premiumDebt
    1597
        );
    1598
    1599
        {
    1600
          ISpoke.UserPosition memory userPosition = spoke.getUserPosition(reserveId, user);
    1601
          uint256 assetId = spoke.getReserve(reserveId).assetId;
    1602
          IHub hub = IHub(address(spoke.getReserve(reserveId).hub));
    1603
          uint256 premiumDebtRay = _calculatePremiumDebtRay(
    1604
            hub,
    1605
            assetId,
    1606
            userPosition.premiumShares,
    1607
            userPosition.premiumOffsetRay
    1608
          );
    1609
    1610
          uint256 restoredPremiumRay = (premiumAmountToRestore * WadRayMath.RAY).min(premiumDebtRay);
    1611
          uint256 restoredShares = drawnDebtToRestore.rayDivDown(hub.getAssetDrawnIndex(reserveId));
    1612
          uint256 riskPremium = _getUserLastRiskPremium(spoke, user);
    1613
    1614
          return
    1615
            _getExpectedPremiumDelta({
    1616
              hub: hub,
    1617
              assetId: assetId,
    1618
              oldPremiumShares: userPosition.premiumShares,
    1619
              oldPremiumOffsetRay: userPosition.premiumOffsetRay,
    1620
              drawnShares: userPosition.drawnShares - restoredShares,
    1621
              riskPremium: riskPremium,
    1622
              restoredPremiumRay: restoredPremiumRay
    1623
            });
    1624
        }
    1625
      }
    1626
    1627
      /// @dev Helper function to check consistent supplied amounts within accounting
    1628
      function _checkSuppliedAmounts(
    1629
        uint256 assetId,
    1630
        uint256 reserveId,
    1631
        ISpoke spoke,
    1632
        address user,
    1633
        uint256 expectedSuppliedAmount,
    1634
        string memory label
    1635
      ) internal view {
    1636
        uint256 expectedSuppliedShares = hub1.previewAddByAssets(assetId, expectedSuppliedAmount);
    1637
        assertEq(
    1638
          hub1.getAddedShares(assetId),
    1639
          expectedSuppliedShares,
    1640
          string(abi.encodePacked('asset supplied shares ', label))
    1641
        );
    1642
        assertEq(
    1643
          hub1.getAddedAssets(assetId) - _calculateBurntInterest(hub1, assetId),
    1644
          expectedSuppliedAmount,
    1645
          string(abi.encodePacked('asset supplied amount ', label))
    1646
        );
    1647
        assertEq(
    1648
          hub1.getSpokeAddedShares(assetId, address(spoke)),
    1649
          expectedSuppliedShares,
    1650
          string(abi.encodePacked('spoke supplied shares ', label))
    1651
        );
    1652
        assertEq(
    1653
          hub1.getSpokeAddedAssets(assetId, address(spoke)),
    1654
          expectedSuppliedAmount,
    1655
          string(abi.encodePacked('spoke supplied amount ', label))
    1656
        );
    1657
        assertEq(
    1658
          spoke.getReserveSuppliedShares(reserveId),
    1659
          expectedSuppliedShares,
    1660
          string(abi.encodePacked('reserve supplied shares ', label))
    1661
        );
    1662
        assertEq(
    1663
          spoke.getReserveSuppliedAssets(reserveId),
    1664
          expectedSuppliedAmount,
    1665
          string(abi.encodePacked('reserve supplied amount ', label))
    1666
        );
    1667
        assertEq(
    1668
          spoke.getUserSuppliedShares(reserveId, user),
    1669
          expectedSuppliedShares,
    1670
          string(abi.encodePacked('user supplied shares ', label))
    1671
        );
    1672
        assertEq(
    1673
          spoke.getUserSuppliedAssets(reserveId, user),
    1674
          expectedSuppliedAmount,
    1675
          string(abi.encodePacked('user supplied amount ', label))
    1676
        );
    1677
      }
    1678
    1679
      function _assertUserDebt(
    1680
        ISpoke spoke,
    1681
        uint256 reserveId,
    1682
        address user,
    1683
        uint256 expectedDrawnDebt,
    1684
        uint256 expectedPremiumDebt,
    1685
        string memory label
    1686
      ) internal view {
    1687
        (uint256 actualDrawnDebt, uint256 actualPremiumDebt) = spoke.getUserDebt(reserveId, user);
    1688
        assertApproxEqAbs(
    1689
          actualDrawnDebt,
    1690
          expectedDrawnDebt,
    1691
          1,
    1692
          string.concat('user drawn debt ', label)
    1693
        );
    1694
        assertApproxEqAbs(
    1695
          actualPremiumDebt,
    1696
          expectedPremiumDebt,
    1697
          3,
    1698
          string.concat('user premium debt ', label)
    1699
        );
    1700
        assertApproxEqAbs(
    1701
          spoke.getUserTotalDebt(reserveId, user),
    1702
          expectedDrawnDebt + expectedPremiumDebt,
    1703
          3,
    1704
          string.concat('user total debt ', label)
    1705
        );
    1706
      }
    1707
    1708
      function _assertReserveDebt(
    1709
        ISpoke spoke,
    1710
        uint256 reserveId,
    1711
        uint256 expectedDrawnDebt,
    1712
        uint256 expectedPremiumDebt,
    1713
        string memory label
    1714
      ) internal view {
    1715
        (uint256 actualDrawnDebt, uint256 actualPremiumDebt) = spoke.getReserveDebt(reserveId);
    1716
        assertApproxEqAbs(
    1717
          actualDrawnDebt,
    1718
          expectedDrawnDebt,
    1719
          1,
    1720
          string.concat('reserve drawn debt ', label)
    1721
        );
    1722
        assertApproxEqAbs(
    1723
          actualPremiumDebt,
    1724
          expectedPremiumDebt,
    1725
          3,
    1726
          string.concat('reserve premium debt ', label)
    1727
        );
    1728
        assertApproxEqAbs(
    1729
          spoke.getReserveTotalDebt(reserveId),
    1730
          expectedDrawnDebt + expectedPremiumDebt,
    1731
          3,
    1732
          string.concat('reserve total debt ', label)
    1733
        );
    1734
      }
    1735
    1736
      function _assertSpokeDebt(
    1737
        ISpoke spoke,
    1738
        uint256 reserveId,
    1739
        uint256 expectedDrawnDebt,
    1740
        uint256 expectedPremiumDebt,
    1741
        string memory label
    1742
      ) internal view {
    1743
        uint256 assetId = spoke.getReserve(reserveId).assetId;
    1744
        (uint256 actualDrawnDebt, uint256 actualPremiumDebt) = hub1.getSpokeOwed(
    1745
          assetId,
    1746
          address(spoke)
    1747
        );
    1748
        assertApproxEqAbs(
    1749
          actualDrawnDebt,
    1750
          expectedDrawnDebt,
    1751
          1,
    1752
          string.concat('spoke drawn debt ', label)
    1753
        );
    1754
        assertApproxEqAbs(
    1755
          actualPremiumDebt,
    1756
          expectedPremiumDebt,
    1757
          3,
    1758
          string.concat('spoke premium debt ', label)
    1759
        );
    1760
        assertApproxEqAbs(
    1761
          hub1.getSpokeTotalOwed(assetId, address(spoke)),
    1762
          expectedDrawnDebt + expectedPremiumDebt,
    1763
          3,
    1764
          string.concat('spoke total debt ', label)
    1765
        );
    1766
      }
    1767
    1768
      function _assertAssetDebt(
    1769
        ISpoke spoke,
    1770
        uint256 reserveId,
    1771
        uint256 expectedDrawnDebt,
    1772
        uint256 expectedPremiumDebt,
    1773
        string memory label
    1774
      ) internal view {
    1775
        uint256 assetId = spoke.getReserve(reserveId).assetId;
    1776
        (uint256 actualDrawnDebt, uint256 actualPremiumDebt) = hub1.getAssetOwed(assetId);
    1777
        assertApproxEqAbs(
    1778
          actualDrawnDebt,
    1779
          expectedDrawnDebt,
    1780
          1,
    1781
          string.concat('asset drawn debt ', label)
    1782
        );
    1783
        assertApproxEqAbs(
    1784
          actualPremiumDebt,
    1785
          expectedPremiumDebt,
    1786
          3,
    1787
          string.concat('asset premium debt ', label)
    1788
        );
    1789
        assertApproxEqAbs(
    1790
          hub1.getAssetTotalOwed(assetId),
    1791
          expectedDrawnDebt + expectedPremiumDebt,
    1792
          3,
    1793
          string.concat('asset total debt ', label)
    1794
        );
    1795
      }
    1796
    1797
      function _assertSingleUserProtocolDebt(
    1798
        ISpoke spoke,
    1799
        uint256 reserveId,
    1800
        address user,
    1801
        uint256 expectedDrawnDebt,
    1802
        uint256 expectedPremiumDebt,
    1803
        string memory label
    1804
      ) internal view {
    1805
        _assertUserDebt(spoke, reserveId, user, expectedDrawnDebt, expectedPremiumDebt, label);
    1806
    1807
        _assertReserveDebt(spoke, reserveId, expectedDrawnDebt, expectedPremiumDebt, label);
    1808
    1809
        _assertSpokeDebt(spoke, reserveId, expectedDrawnDebt, expectedPremiumDebt, label);
    1810
    1811
        _assertAssetDebt(spoke, reserveId, expectedDrawnDebt, expectedPremiumDebt, label);
    1812
      }
    1813
    1814
      function _assertUserSupply(
    1815
        ISpoke spoke,
    1816
        uint256 reserveId,
    1817
        address user,
    1818
        uint256 expectedSuppliedAmount,
    1819
        string memory label
    1820
      ) internal view {
    1821
        assertApproxEqAbs(
    1822
          spoke.getUserSuppliedAssets(reserveId, user),
    1823
          expectedSuppliedAmount,
    1824
          3,
    1825
          string.concat('user supplied amount ', label)
    1826
        );
    1827
      }
    1828
    1829
      function _assertReserveSupply(
    1830
        ISpoke spoke,
    1831
        uint256 reserveId,
    1832
        uint256 expectedSuppliedAmount,
    1833
        string memory label
    1834
      ) internal view {
    1835
        assertApproxEqAbs(
    1836
          spoke.getReserveSuppliedAssets(reserveId),
    1837
          expectedSuppliedAmount,
    1838
          3,
    1839
          string.concat('reserve supplied amount ', label)
    1840
        );
    1841
      }
    1842
    1843
      function _assertSpokeSupply(
    1844
        ISpoke spoke,
    1845
        uint256 reserveId,
    1846
        uint256 expectedSuppliedAmount,
    1847
        string memory label
    1848
      ) internal view {
    1849
        uint256 assetId = spoke.getReserve(reserveId).assetId;
    1850
        assertApproxEqAbs(
    1851
          hub1.getSpokeAddedAssets(assetId, address(spoke)),
    1852
          expectedSuppliedAmount,
    1853
          3,
    1854
          string.concat('spoke supplied amount ', label)
    1855
        );
    1856
      }
    1857
    1858
      function _assertAssetSupply(
    1859
        ISpoke spoke,
    1860
        uint256 reserveId,
    1861
        uint256 expectedSuppliedAmount,
    1862
        string memory label
    1863
      ) internal view {
    1864
        uint256 assetId = spoke.getReserve(reserveId).assetId;
    1865
        assertApproxEqAbs(
    1866
          hub1.getAddedAssets(assetId) - _calculateBurntInterest(hub1, assetId),
    1867
          expectedSuppliedAmount,
    1868
          3,
    1869
          string.concat('asset supplied amount ', label)
    1870
        );
    1871
      }
    1872
    1873
      function _assertSingleUserProtocolSupply(
    1874
        ISpoke spoke,
    1875
        uint256 reserveId,
    1876
        address user,
    1877
        uint256 expectedSuppliedAmount,
    1878
        string memory label
    1879
      ) internal view {
    1880
        _assertUserSupply(spoke, reserveId, user, expectedSuppliedAmount, label);
    1881
    1882
        _assertReserveSupply(spoke, reserveId, expectedSuppliedAmount, label);
    1883
    1884
        _assertSpokeSupply(spoke, reserveId, expectedSuppliedAmount, label);
    1885
    1886
        _assertAssetSupply(spoke, reserveId, expectedSuppliedAmount, label);
    1887
      }
    1888
    1889
      function _convertAmountToValue(
    1890
        ISpoke spoke,
    1891
        uint256 reserveId,
    1892
        uint256 amount
    1893
      ) internal view returns (uint256) {
    1894
        return
    1895
          _convertAmountToValue(
    1896
            amount,
    1897
            IPriceOracle(spoke.ORACLE()).getReservePrice(reserveId),
    1898
            10 ** _underlying(spoke, reserveId).decimals()
    1899
          );
    1900
      }
    1901
    1902
      function _convertAmountToValue(
    1903
        uint256 amount,
    1904
        uint256 assetPrice,
    1905
        uint256 assetUnit
    1906
      ) internal pure returns (uint256) {
    1907
        return (amount * assetPrice).wadDivUp(assetUnit);
    1908
      }
    1909
    1910
      function _convertValueToAmount(
    1911
        ISpoke spoke,
    1912
        uint256 reserveId,
    1913
        uint256 valueAmount
    1914
      ) internal view returns (uint256) {
    1915
        return
    1916
          _convertValueToAmount(
    1917
            valueAmount,
    1918
            IPriceOracle(spoke.ORACLE()).getReservePrice(reserveId),
    1919
            10 ** _underlying(spoke, reserveId).decimals()
    1920
          );
    1921
      }
    1922
    1923
      function _convertValueToAmount(
    1924
        uint256 valueAmount,
    1925
        uint256 assetPrice,
    1926
        uint256 assetUnit
    1927
      ) internal pure returns (uint256) {
    1928
        return ((valueAmount * assetUnit) / assetPrice).fromWadDown();
    1929
      }
    1930
    1931
      /**
    1932
       * @notice Returns the required debt amount to ensure user position is ~ a certain health factor.
    1933
       * @param desiredHf The desired health factor to be at.
    1934
       */
    1935
      function _getRequiredDebtAmountForHf(
    1936
        ISpoke spoke,
    1937
        address user,
    1938
        uint256 reserveId,
    1939
        uint256 desiredHf
    1940
      ) internal view returns (uint256 requiredDebtAmount) {
    1941
        uint256 requiredDebtAmountValue = _getRequiredDebtValueForHf(spoke, user, desiredHf);
    1942
        return _convertValueToAmount(spoke, reserveId, requiredDebtAmountValue);
    1943
      }
    1944
    1945
      /**
    1946
       * @notice Returns the required debt in value terms to ensure user position is below a certain health factor.
    1947
       */
    1948
      function _getRequiredDebtValueForHf(
    1949
        ISpoke spoke,
    1950
        address user,
    1951
        uint256 desiredHf
    1952
      ) internal view returns (uint256 requiredDebtValue) {
    1953
        ISpoke.UserAccountData memory userAccountData = spoke.getUserAccountData(user);
    1954
    1955
        requiredDebtValue =
    1956
          userAccountData.totalCollateralValue.wadMulUp(userAccountData.avgCollateralFactor).wadDivUp(
    1957
            desiredHf
    1958
          ) -
    1959
          userAccountData.totalDebtValue;
    1960
      }
    1961
    1962
      function _getUserHealthFactor(ISpoke spoke, address user) internal view returns (uint256) {
    1963
        return spoke.getUserAccountData(user).healthFactor;
    1964
      }
    1965
    1966
      function _getUserLastRiskPremium(ISpoke spoke, address user) internal view returns (uint256) {
    1967
        return spoke.getUserLastRiskPremium(user);
    1968
      }
    1969
    1970
      function _getUserRiskPremium(ISpoke spoke, address user) internal view returns (uint256) {
    1971
        return spoke.getUserAccountData(user).riskPremium;
    1972
      }
    1973
    1974
      function _approxRelFromBps(uint256 bps) internal pure returns (uint256) {
    1975
        return (bps * 1e18) / 100_00;
    1976
      }
    1977
    1978
      function _min(uint256 a, uint256 b) internal pure returns (uint256) {
    1979
        return a < b ? a : b;
    1980
      }
    1981
    1982
      function _max(uint256 a, uint256 b) internal pure returns (uint256) {
    1983
        return a > b ? a : b;
    1984
      }
    1985
    1986
      function _getTargetHealthFactor(ISpoke spoke) internal view returns (uint128) {
    1987
        return spoke.getLiquidationConfig().targetHealthFactor;
    1988
      }
    1989
    1990
      function _calcMinimumCollAmount(
    1991
        ISpoke spoke,
    1992
        uint256 collReserveId,
    1993
        uint256 debtReserveId,
    1994
        uint256 debtAmount
    1995
      ) internal view returns (uint256) {
    1996
        if (debtAmount == 0) return 1;
    1997
        IPriceOracle oracle = IPriceOracle(spoke.ORACLE());
    1998
        ISpoke.Reserve memory collData = spoke.getReserve(collReserveId);
    1999
        ISpoke.DynamicReserveConfig memory collDynConf = _getLatestDynamicReserveConfig(
    2000
          spoke,
    2001
          collReserveId
    2002
        );
    2003
    2004
        uint256 collPrice = oracle.getReservePrice(collReserveId);
    2005
        uint256 collAssetUnits = 10 ** hub1.getAsset(collData.assetId).decimals;
    2006
    2007
        ISpoke.Reserve memory debtData = spoke.getReserve(debtReserveId);
    2008
        uint256 debtAssetUnits = 10 ** hub1.getAsset(debtData.assetId).decimals;
    2009
        uint256 debtPrice = oracle.getReservePrice(debtReserveId);
    2010
    2011
        uint256 normalizedDebtAmount = (debtAmount * debtPrice).wadDivDown(debtAssetUnits);
    2012
        uint256 normalizedCollPrice = collPrice.wadDivDown(collAssetUnits);
    2013
    2014
        return
    2015
          normalizedDebtAmount.wadDivUp(
    2016
            normalizedCollPrice.toWad().percentMulDown(collDynConf.collateralFactor)
    2017
          );
    2018
      }
    2019
    2020
      /// @dev Calculate expected debt index based on input params
    2021
      function _calculateExpectedDrawnIndex(
    2022
        uint256 initialDrawnIndex,
    2023
        uint96 borrowRate,
    2024
        uint40 startTime
    2025
      ) internal view returns (uint256) {
    2026
        return initialDrawnIndex.rayMulUp(MathUtils.calculateLinearInterest(borrowRate, startTime));
    2027
      }
    2028
    2029
      /// @dev Calculate expected debt index and drawn debt based on input params
    2030
      function calculateExpectedDebt(
    2031
        uint256 initialDrawnShares,
    2032
        uint256 initialDrawnIndex,
    2033
        uint96 borrowRate,
    2034
        uint40 startTime
    2035
      ) internal view returns (uint256 newDrawnIndex, uint256 newDrawnDebt) {
    2036
        newDrawnIndex = _calculateExpectedDrawnIndex(initialDrawnIndex, borrowRate, startTime);
    2037
        newDrawnDebt = initialDrawnShares.rayMulUp(newDrawnIndex);
    2038
      }
    2039
    2040
      /// @dev Calculate expected drawn debt based on specified borrow rate
    2041
      function _calculateExpectedDrawnDebt(
    2042
        uint256 initialDebt,
    2043
        uint96 borrowRate,
    2044
        uint40 startTime
    2045
      ) internal view returns (uint256) {
    2046
        return MathUtils.calculateLinearInterest(borrowRate, startTime).rayMulUp(initialDebt);
    2047
      }
    2048
    2049
      /// @dev Calculate expected premium debt based on change in drawn debt and user rp
    2050
      function _calculateExpectedPremiumDebt(
    2051
        uint256 initialDrawnDebt,
    2052
        uint256 currentDrawnDebt,
    2053
        uint256 userRiskPremium
    2054
      ) internal pure returns (uint256) {
    2055
        return (currentDrawnDebt - initialDrawnDebt).percentMulUp(userRiskPremium);
    2056
      }
    2057
    2058
      /// @dev Helper function to get asset drawn debt
    2059
      function getAssetDrawnDebt(uint256 assetId) internal view returns (uint256) {
    2060
        (uint256 drawn, ) = hub1.getAssetOwed(assetId);
    2061
        return drawn;
    2062
      }
    2063
    2064
      /// @dev Helper function to calculate burnt interest in assets terms (originated from virtual shares and assets)
    2065
      function _calculateBurntInterest(IHub hub, uint256 assetId) internal view returns (uint256) {
    2066
        return
    2067
          hub.getAddedAssets(assetId) - hub.previewRemoveByShares(assetId, hub.getAddedShares(assetId));
    2068
      }
    2069
    2070
      function _calculatePremiumDebt(
    2071
        IHub hub,
    2072
        uint256 assetId,
    2073
        uint256 premiumShares,
    2074
        int256 premiumOffsetRay
    2075
      ) internal view returns (uint256) {
    2076
        return _calculatePremiumDebtRay(hub, assetId, premiumShares, premiumOffsetRay).fromRayUp();
    2077
      }
    2078
    2079
      function _calculatePremiumDebtRay(
    2080
        IHub hub,
    2081
        uint256 assetId,
    2082
        uint256 premiumShares,
    2083
        int256 premiumOffsetRay
    2084
      ) internal view returns (uint256) {
    2085
        uint256 drawnIndex = hub.getAssetDrawnIndex(assetId);
    2086
        return _calculatePremiumDebtRay(premiumShares, premiumOffsetRay, drawnIndex);
    2087
      }
    2088
    2089
      function _calculatePremiumDebtRay(
    2090
        uint256 premiumShares,
    2091
        int256 premiumOffsetRay,
    2092
        uint256 drawnIndex
    2093
      ) internal pure returns (uint256) {
    2094
        return ((premiumShares * drawnIndex).toInt256() - premiumOffsetRay).toUint256();
    2095
      }
    2096
    2097
      function _calculatePremiumDebtRay(
    2098
        ISpoke spoke,
    2099
        uint256 reserveId,
    2100
        uint256 premiumShares,
    2101
        int256 premiumOffsetRay
    2102
      ) internal view returns (uint256) {
    2103
        IHub hub = _hub(spoke, reserveId);
    2104
        uint256 assetId = spoke.getReserve(reserveId).assetId;
    2105
        return _calculatePremiumDebtRay(hub, assetId, premiumShares, premiumOffsetRay);
    2106
      }
    2107
    2108
      function _calculatePremiumDebtRay(
    2109
        ISpoke spoke,
    2110
        uint256 reserveId,
    2111
        address user
    2112
      ) internal view returns (uint256) {
    2113
        ISpoke.UserPosition memory userPosition = spoke.getUserPosition(reserveId, user);
    2114
        return
    2115
          _calculatePremiumDebtRay(
    2116
            spoke,
    2117
            reserveId,
    2118
            userPosition.premiumShares,
    2119
            userPosition.premiumOffsetRay
    2120
          );
    2121
      }
    2122
    2123
      function _calculatePremiumAssetsRay(
    2124
        uint256 premiumShares,
    2125
        uint256 drawnIndex
    2126
      ) internal pure returns (uint256) {
    2127
        return premiumShares * drawnIndex;
    2128
      }
    2129
    2130
      function _calculatePremiumAssetsRay(
    2131
        IHub hub,
    2132
        uint256 assetId,
    2133
        uint256 premiumShares
    2134
      ) internal view returns (uint256) {
    2135
        return _calculatePremiumAssetsRay(premiumShares, hub.getAssetDrawnIndex(assetId));
    2136
      }
    2137
    2138
      /// @dev Helper function to withdraw fees from the treasury spoke
    2139
      function _withdrawLiquidityFees(IHub hub, uint256 assetId, uint256 amount) internal {
    2140
        Utils.mintFeeShares(hub, assetId, ADMIN);
    2141
        uint256 fees = hub.getSpokeAddedAssets(assetId, address(treasurySpoke));
    2142
    2143
        if (amount > fees) {
    2144
          amount = fees;
    2145
        }
    2146
        if (amount == 0) {
    2147
          return; // nothing to withdraw
    2148
        }
    2149
        vm.prank(TREASURY_ADMIN);
    2150
        treasurySpoke.withdraw(assetId, amount, address(treasurySpoke));
    2151
      }
    2152
    2153
      function _assumeValidSupplier(address user) internal view {
    2154
        vm.assume(
    2155
          user != address(0) &&
    2156
            user != address(hub1) &&
    2157
            user != address(spoke1) &&
    2158
            user != address(spoke2) &&
    2159
            user != address(spoke3) &&
    2160
            user != _getProxyAdminAddress(address(spoke1)) &&
    2161
            user != _getProxyAdminAddress(address(spoke2)) &&
    2162
            user != _getProxyAdminAddress(address(spoke3))
    2163
        );
    2164
      }
    2165
    2166
      function _getAssetLiquidityFee(uint256 assetId) internal view returns (uint256) {
    2167
        return hub1.getAssetConfig(assetId).liquidityFee;
    2168
      }
    2169
    2170
      function _getFeeReceiver(IHub hub, uint256 assetId) internal view returns (address) {
    2171
        return hub.getAssetConfig(assetId).feeReceiver;
    2172
      }
    2173
    2174
      function _getFeeReceiver(ISpoke spoke, uint256 reserveId) internal view returns (address) {
    2175
        return _getFeeReceiver(_hub(spoke, reserveId), spoke.getReserve(reserveId).assetId);
    2176
      }
    2177
    2178
      function _getCollateralRisk(ISpoke spoke, uint256 reserveId) internal view returns (uint24) {
    2179
        return spoke.getReserveConfig(reserveId).collateralRisk;
    2180
      }
    2181
    2182
      function _getCollateralFactor(ISpoke spoke, uint256 reserveId) internal view returns (uint16) {
    2183
        return _getLatestDynamicReserveConfig(spoke, reserveId).collateralFactor;
    2184
      }
    2185
    2186
      function _getCollateralFactor(
    2187
        ISpoke spoke,
    2188
        uint256 reserveId,
    2189
        address user
    2190
      ) internal view returns (uint16) {
    2191
        uint24 dynamicConfigKey = spoke.getUserPosition(reserveId, user).dynamicConfigKey;
    2192
        return spoke.getDynamicReserveConfig(reserveId, dynamicConfigKey).collateralFactor;
    2193
      }
    2194
    2195
      function _getCollateralFactor(
    2196
        ISpoke spoke,
    2197
        function(ISpoke) internal view returns (uint256) reserveId
    2198
      ) internal view returns (uint16) {
    2199
        return _getLatestDynamicReserveConfig(spoke, reserveId(spoke)).collateralFactor;
    2200
      }
    2201
    2202
      function _hasRole(
    2203
        IAccessManager authority,
    2204
        uint64 role,
    2205
        address account
    2206
      ) internal view returns (bool) {
    2207
        (bool hasRole, ) = authority.hasRole(role, account);
    2208
        return hasRole;
    2209
      }
    2210
    2211
      function _randomBps() internal returns (uint16) {
    2212
        return vm.randomUint(0, PercentageMath.PERCENTAGE_FACTOR).toUint16();
    2213
      }
    2214
    2215
      function _hub(ISpoke spoke, uint256 reserveId) internal view returns (IHub) {
    2216
        return IHub(address(spoke.getReserve(reserveId).hub));
    2217
      }
    2218
    2219
      function _spokeAssetId(ISpoke spoke, uint256 reserveId) internal view returns (uint256) {
    2220
        return spoke.getReserve(reserveId).assetId;
    2221
      }
    2222
    2223
      function _underlying(ISpoke spoke, uint256 reserveId) internal view returns (TestnetERC20) {
    2224
        return TestnetERC20(spoke.getReserve(reserveId).underlying);
    2225
      }
    2226
    2227
      function _approveAllUnderlying(ISpoke spoke, address owner, address spender) internal {
    2228
        for (uint256 reserveId; reserveId < spoke.getReserveCount(); ++reserveId) {
    2229
          TestnetERC20 underlying = _underlying(spoke, reserveId);
    2230
          vm.prank(owner);
    2231
          underlying.approve(spender, UINT256_MAX);
    2232
        }
    2233
      }
    2234
    2235
      function _deploySpokeWithOracle(
    2236
        address /*proxyAdminOwner*/,
    2237
        address _accessManager,
    2238
        string memory _oracleDesc
    2239
      ) internal returns (ISpoke, IAaveOracle) {
    2240
        // address deployer = makeAddr('deployer');
    2241
        // address predictedSpoke = vm.computeCreateAddress(deployer, vm.getNonce(deployer));
    2242
        IAaveOracle oracle = new AaveOracle(address(1), 8, _oracleDesc);
    2243
        SpokeInstance spokeImpl = new SpokeInstance(address(oracle));
    2244
        spokeImpl.initialize(_accessManager);
    2245
        ISpoke spoke = ISpoke(
    2246
          spokeImpl
    2247
          // _proxify(
    2248
          //   deployer,
    2249
          //   spokeImpl,
    2250
          //   proxyAdminOwner,
    2251
          //   abi.encodeCall(Spoke.initialize, (_accessManager))
    2252
          // )
    2253
        );
    2254
        AaveOracle(address(oracle)).setSpoke(address(spoke));
    2255
        // assertEq(address(spoke), predictedSpoke, 'predictedSpoke');
    2256
        _assertEq(spoke.ORACLE(), address(oracle));
    2257
        _assertEq(oracle.SPOKE(), address(spoke));
    2258
        return (spoke, oracle);
    2259
      }
    2260
    2261
      function _getDefaultReserveConfig(
    2262
        uint24 collateralRisk
    2263
      ) internal pure returns (ISpoke.ReserveConfig memory) {
    2264
        return
    2265
          ISpoke.ReserveConfig({
    2266
            paused: false,
    2267
            frozen: false,
    2268
            borrowable: true,
    2269
            liquidatable: true,
    2270
            receiveSharesEnabled: true,
    2271
            collateralRisk: collateralRisk
    2272
          });
    2273
      }
    2274
    2275
      function _proxify(
    2276
        address deployer,
    2277
        address impl,
    2278
        address proxyAdminOwner,
    2279
        bytes memory initData
    2280
      ) internal returns (address) {
    2281
        vm.prank(deployer);
    2282
        TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
    2283
          impl,
    2284
          proxyAdminOwner,
    2285
          initData
    2286
        );
    2287
        return address(proxy);
    2288
      }
    2289
    2290
      function assertEq(IHubBase.PremiumDelta memory a, IHubBase.PremiumDelta memory b) internal pure {
    2291
        assertEq(a.sharesDelta, b.sharesDelta, 'sharesDelta');
    2292
        assertEq(a.offsetRayDelta, b.offsetRayDelta, 'offsetRayDelta');
    2293
        assertEq(a.restoredPremiumRay, b.restoredPremiumRay, 'restoredPremiumRay');
    2294
        assertEq(abi.encode(a), abi.encode(b));
    2295
      }
    2296
    2297
      function assertEq(IHub.AssetConfig memory a, IHub.AssetConfig memory b) internal pure {
    2298
        assertEq(a.feeReceiver, b.feeReceiver, 'feeReceiver');
    2299
        assertEq(a.liquidityFee, b.liquidityFee, 'liquidityFee');
    2300
        assertEq(a.irStrategy, b.irStrategy, 'irStrategy');
    2301
        assertEq(a.reinvestmentController, b.reinvestmentController, 'reinvestmentController');
    2302
        assertEq(abi.encode(a), abi.encode(b));
    2303
      }
    2304
    2305
      function assertEq(IHub.SpokeConfig memory a, IHub.SpokeConfig memory b) internal pure {
    2306
        assertEq(a.addCap, b.addCap, 'addCap');
    2307
        assertEq(a.drawCap, b.drawCap, 'drawCap');
    2308
        assertEq(a.riskPremiumThreshold, b.riskPremiumThreshold, 'riskPremiumThreshold');
    2309
        assertEq(a.active, b.active, 'active');
    2310
        assertEq(a.paused, b.paused, 'paused');
    2311
        assertEq(abi.encode(a), abi.encode(b));
    2312
      }
    2313
    2314
      function assertEq(
    2315
        ISpoke.LiquidationConfig memory a,
    2316
        ISpoke.LiquidationConfig memory b
    2317
      ) internal pure {
    2318
        assertEq(a.targetHealthFactor, b.targetHealthFactor, 'targetHealthFactor');
    2319
        assertEq(a.liquidationBonusFactor, b.liquidationBonusFactor, 'liquidationBonusFactor');
    2320
        assertEq(a.healthFactorForMaxBonus, b.healthFactorForMaxBonus, 'healthFactorForMaxBonus');
    2321
        assertEq(abi.encode(a), abi.encode(b));
    2322
      }
    2323
    2324
      function assertEq(ISpoke.ReserveConfig memory a, ISpoke.ReserveConfig memory b) internal pure {
    2325
        assertEq(a.paused, b.paused, 'paused');
    2326
        assertEq(a.frozen, b.frozen, 'frozen');
    2327
        assertEq(a.borrowable, b.borrowable, 'borrowable');
    2328
        assertEq(a.receiveSharesEnabled, b.receiveSharesEnabled, 'receiveSharesEnabled');
    2329
        assertEq(a.collateralRisk, b.collateralRisk, 'collateralRisk');
    2330
        assertEq(abi.encode(a), abi.encode(b));
    2331
      }
    2332
    2333
      function assertEq(
    2334
        ISpoke.DynamicReserveConfig memory a,
    2335
        ISpoke.DynamicReserveConfig memory b
    2336
      ) internal pure {
    2337
        assertEq(a.collateralFactor, b.collateralFactor, 'collateralFactor');
    2338
        assertEq(a.maxLiquidationBonus, b.maxLiquidationBonus, 'maxLiquidationBonus');
    2339
        assertEq(a.liquidationFee, b.liquidationFee, 'liquidationFee');
    2340
        assertEq(abi.encode(a), abi.encode(b));
    2341
      }
    2342
    2343
      function assertEq(
    2344
        IAssetInterestRateStrategy.InterestRateData memory a,
    2345
        IAssetInterestRateStrategy.InterestRateData memory b
    2346
      ) internal pure {
    2347
        assertEq(a.optimalUsageRatio, b.optimalUsageRatio, 'optimalUsageRatio');
    2348
        assertEq(a.baseVariableBorrowRate, b.baseVariableBorrowRate, 'baseVariableBorrowRate');
    2349
        assertEq(a.variableRateSlope1, b.variableRateSlope1, 'variableRateSlope1');
    2350
        assertEq(a.variableRateSlope2, b.variableRateSlope2, 'variableRateSlope2');
    2351
        assertEq(abi.encode(a), abi.encode(b));
    2352
      }
    2353
    2354
      function _assertEq(address a, address b, string memory errorMessage) internal pure {
    2355
        if (a != b) {
    2356
          console.log('a', a);
    2357
          console.log('b', b);
    2358
          console.log('errorMessage', errorMessage);
    2359
        }
    2360
        require(a == b, errorMessage);
    2361
      }
    2362
    2363
      function _assertEq(address a, address b) internal pure {
    2364
        _assertEq(a, b, "address mismatch");
    2365
      }
    2366
    2367
      function _calculateExpectedFees(
    2368
        uint256 drawnIncrease,
    2369
        uint256 premiumIncrease,
    2370
        uint256 liquidityFee
    2371
      ) internal pure returns (uint256) {
    2372
        return (drawnIncrease + premiumIncrease).percentMulDown(liquidityFee);
    2373
      }
    2374
    2375
      function _calculateExpectedFeesAmount(
    2376
        uint256 initialDrawnShares,
    2377
        uint256 initialPremiumShares,
    2378
        uint256 liquidityFee,
    2379
        uint256 indexDelta
    2380
      ) internal pure returns (uint256 feesAmount) {
    2381
        return
    2382
          indexDelta.rayMulUp(initialDrawnShares + initialPremiumShares).percentMulDown(liquidityFee);
    2383
      }
    2384
    2385
      /// @dev Get the liquidation bonus for a given reserve at a user HF
    2386
      function _getLiquidationBonus(
    2387
        ISpoke spoke,
    2388
        uint256 reserveId,
    2389
        address user,
    2390
        uint256 healthFactor
    2391
      ) internal view returns (uint256) {
    2392
        return spoke.getLiquidationBonus(reserveId, user, healthFactor);
    2393
      }
    2394
    2395
      /**
    2396
       * @notice Returns the required debt amount in value terms to ensure user position is above a certain health factor.
    2397
       * @return requiredDebt The required additional debt amount in value terms.
    2398
       */
    2399
      function _getRequiredDebtForGtHf(
    2400
        ISpoke spoke,
    2401
        address user,
    2402
        uint256 desiredHf
    2403
      ) internal view returns (uint256) {
    2404
        ISpoke.UserAccountData memory userAccountData = spoke.getUserAccountData(user);
    2405
    2406
        return
    2407
          userAccountData
    2408
            .totalCollateralValue
    2409
            .percentMulDown(userAccountData.avgCollateralFactor.fromWadDown())
    2410
            .percentMulDown(99_00)
    2411
            .wadDivDown(desiredHf) - userAccountData.totalDebtValue;
    2412
        // buffer to force debt lower (ie making sure resultant debt creates HF that is gt desired)
    2413
      }
    2414
    2415
      /// @dev Borrow to be below a certain healthy health factor
    2416
      /// @dev This function validates HF and does not mock price, thus it will cache user RP properly
    2417
      function _borrowToBeAboveHealthyHf(
    2418
        ISpoke spoke,
    2419
        address user,
    2420
        uint256 reserveId,
    2421
        uint256 desiredHf
    2422
      ) internal returns (uint256, uint256) {
    2423
        uint256 requiredDebtInBase = _getRequiredDebtForGtHf(spoke, user, desiredHf);
    2424
        uint256 requiredDebtAmount = _convertValueToAmount(spoke, reserveId, requiredDebtInBase) - 1;
    2425
    2426
        vm.assume(requiredDebtAmount < MAX_SUPPLY_AMOUNT);
    2427
    2428
        vm.prank(user);
    2429
        spoke.borrow(reserveId, requiredDebtAmount, user);
    2430
    2431
        uint256 finalHf = _getUserHealthFactor(spoke, user);
    2432
        assertGt(finalHf, desiredHf, 'should borrow so that HF is above desiredHf');
    2433
        return (finalHf, requiredDebtAmount);
    2434
      }
    2435
    2436
      function _mockDecimals(address underlying, uint8 decimals) internal {
    2437
        vm.mockCall(
    2438
          underlying,
    2439
          abi.encodeWithSelector(IERC20Metadata.decimals.selector),
    2440
          abi.encode(decimals)
    2441
        );
    2442
      }
    2443
    2444
      function _mockInterestRateBps(uint256 interestRateBps) internal {
    2445
        _mockInterestRateBps(address(irStrategy), interestRateBps);
    2446
      }
    2447
    2448
      function _mockInterestRateBps(address interestRateStrategy, uint256 interestRateBps) internal {
    2449
        vm.mockCall(
    2450
          interestRateStrategy,
    2451
          IBasicInterestRateStrategy.calculateInterestRate.selector,
    2452
          abi.encode(interestRateBps.bpsToRay())
    2453
        );
    2454
      }
    2455
    2456
      function _mockInterestRateBps(
    2457
        uint256 interestRateBps,
    2458
        uint256 assetId,
    2459
        uint256 liquidity,
    2460
        uint256 drawn,
    2461
        uint256 deficit,
    2462
        uint256 swept
    2463
      ) internal {
    2464
        _mockInterestRateBps(
    2465
          address(irStrategy),
    2466
          interestRateBps,
    2467
          assetId,
    2468
          liquidity,
    2469
          drawn,
    2470
          deficit,
    2471
          swept
    2472
        );
    2473
      }
    2474
    2475
      function _mockInterestRateBps(
    2476
        address interestRateStrategy,
    2477
        uint256 interestRateBps,
    2478
        uint256 assetId,
    2479
        uint256 liquidity,
    2480
        uint256 drawn,
    2481
        uint256 deficit,
    2482
        uint256 swept
    2483
      ) internal {
    2484
        vm.mockCall(
    2485
          interestRateStrategy,
    2486
          abi.encodeCall(
    2487
            IBasicInterestRateStrategy.calculateInterestRate,
    2488
            (assetId, liquidity, drawn, deficit, swept)
    2489
          ),
    2490
          abi.encode(interestRateBps.bpsToRay())
    2491
        );
    2492
      }
    2493
    2494
      function _mockInterestRateRay(uint256 interestRateRay) internal {
    2495
        _mockInterestRateRay(address(irStrategy), interestRateRay);
    2496
      }
    2497
    2498
      function _mockInterestRateRay(address interestRateStrategy, uint256 interestRateRay) internal {
    2499
        vm.mockCall(
    2500
          interestRateStrategy,
    2501
          IBasicInterestRateStrategy.calculateInterestRate.selector,
    2502
          abi.encode(interestRateRay)
    2503
        );
    2504
      }
    2505
    2506
      function _mockInterestRateRay(
    2507
        uint256 interestRateRay,
    2508
        uint256 assetId,
    2509
        uint256 liquidity,
    2510
        uint256 drawn
    2511
      ) internal {
    2512
        _mockInterestRateRay(address(irStrategy), interestRateRay, assetId, liquidity, drawn, 0, 0);
    2513
      }
    2514
    2515
      function _mockInterestRateRay(
    2516
        address interestRateStrategy,
    2517
        uint256 interestRateRay,
    2518
        uint256 assetId,
    2519
        uint256 liquidity,
    2520
        uint256 drawn,
    2521
        uint256 deficit,
    2522
        uint256 swept
    2523
      ) internal {
    2524
        vm.mockCall(
    2525
          interestRateStrategy,
    2526
          abi.encodeCall(
    2527
            IBasicInterestRateStrategy.calculateInterestRate,
    2528
            (assetId, liquidity, drawn, deficit, swept)
    2529
          ),
    2530
          abi.encode(interestRateRay)
    2531
        );
    2532
      }
    2533
    2534
      function _mockReservePrice(ISpoke spoke, uint256 reserveId, uint256 price) internal {
    2535
        require(price > 0, 'mockReservePrice: price must be positive');
    2536
        AaveOracle oracle = AaveOracle(spoke.ORACLE());
    2537
        address mockPriceFeed = address(
    2538
          new MockPriceFeed(oracle.DECIMALS(), oracle.DESCRIPTION(), price)
    2539
        );
    2540
        vm.prank(address(ADMIN));
    2541
        spoke.updateReservePriceSource(reserveId, mockPriceFeed);
    2542
      }
    2543
    2544
      function _mockReservePriceByPercent(
    2545
        ISpoke spoke,
    2546
        uint256 reserveId,
    2547
        uint256 percentage
    2548
      ) internal {
    2549
        uint256 initialPrice = IPriceOracle(spoke.ORACLE()).getReservePrice(reserveId);
    2550
        uint256 newPrice = initialPrice.percentMulDown(percentage);
    2551
        _mockReservePrice(spoke, reserveId, newPrice);
    2552
      }
    2553
    2554
      function _deployMockPriceFeed(ISpoke spoke, uint256 price) internal returns (address) {
    2555
        AaveOracle oracle = AaveOracle(spoke.ORACLE());
    2556
        return address(new MockPriceFeed(oracle.DECIMALS(), oracle.DESCRIPTION(), price));
    2557
      }
    2558
    2559
      function _assertBorrowRateSynced(
    2560
        IHub targetHub,
    2561
        uint256 assetId,
    2562
        string memory operation
    2563
      ) internal view {
    2564
        IHub.Asset memory asset = targetHub.getAsset(assetId);
    2565
        (uint256 drawn, ) = hub1.getAssetOwed(assetId);
    2566
    2567
        vm.assertEq(
    2568
          asset.drawnRate,
    2569
          IBasicInterestRateStrategy(asset.irStrategy).calculateInterestRate(
    2570
            assetId,
    2571
            asset.liquidity,
    2572
            drawn,
    2573
            asset.deficitRay,
    2574
            asset.swept
    2575
          ),
    2576
          string.concat('base borrow rate after ', operation)
    2577
        );
    2578
      }
    2579
    2580
      function _assertHubLiquidity(IHub targetHub, uint256 assetId, string memory label) internal view {
    2581
        IHub.Asset memory asset = targetHub.getAsset(assetId);
    2582
        uint256 currentHubBalance = IERC20(asset.underlying).balanceOf(address(targetHub));
    2583
        assertEq(
    2584
          targetHub.getAssetLiquidity(assetId),
    2585
          currentHubBalance,
    2586
          string.concat('hub liquidity ', label)
    2587
        );
    2588
      }
    2589
    2590
      function _assertEventNotEmitted(bytes32 eventSignature) internal {
    2591
        Vm.Log[] memory entries = vm.getRecordedLogs();
    2592
        for (uint256 i; i < entries.length; i++) {
    2593
          assertNotEq(entries[i].topics[0], eventSignature);
    2594
        }
    2595
        vm.recordLogs();
    2596
      }
    2597
    2598
      function _assertEventsNotEmitted(bytes32 event1Sig, bytes32 event2Sig) internal {
    2599
        Vm.Log[] memory entries = vm.getRecordedLogs();
    2600
        for (uint256 i; i < entries.length; i++) {
    2601
          assertNotEq(entries[i].topics[0], event1Sig);
    2602
          assertNotEq(entries[i].topics[0], event2Sig);
    2603
        }
    2604
        vm.recordLogs();
    2605
      }
    2606
    2607
      function _assertEventsNotEmitted(
    2608
        bytes32 event1Sig,
    2609
        bytes32 event2Sig,
    2610
        bytes32 event3Sig
    2611
      ) internal {
    2612
        Vm.Log[] memory entries = vm.getRecordedLogs();
    2613
        for (uint256 i; i < entries.length; i++) {
    2614
          assertNotEq(entries[i].topics[0], event1Sig);
    2615
          assertNotEq(entries[i].topics[0], event2Sig);
    2616
          assertNotEq(entries[i].topics[0], event3Sig);
    2617
        }
    2618
        vm.recordLogs();
    2619
      }
    2620
    2621
      function _assertDynamicConfigRefreshEventsNotEmitted() internal {
    2622
        _assertEventsNotEmitted(
    2623
          ISpoke.RefreshAllUserDynamicConfig.selector,
    2624
          ISpoke.RefreshSingleUserDynamicConfig.selector
    2625
        );
    2626
      }
    2627
    2628
      // @dev Helper function to get asset position, valid if no time has passed since last action
    2629
      function getAssetPosition(
    2630
        IHub hub,
    2631
        uint256 assetId
    2632
      ) internal view returns (AssetPosition memory) {
    2633
        IHub.Asset memory assetData = hub.getAsset(assetId);
    2634
        (uint256 drawn, uint256 premium) = hub.getAssetOwed(assetId);
    2635
        return
    2636
          AssetPosition({
    2637
            assetId: assetId,
    2638
            liquidity: assetData.liquidity,
    2639
            addedShares: assetData.addedShares,
    2640
            addedAmount: hub.getAddedAssets(assetId) - _calculateBurntInterest(hub, assetId),
    2641
            drawnShares: assetData.drawnShares,
    2642
            drawn: drawn,
    2643
            premiumShares: assetData.premiumShares,
    2644
            premiumOffsetRay: assetData.premiumOffsetRay,
    2645
            premium: premium,
    2646
            lastUpdateTimestamp: assetData.lastUpdateTimestamp.toUint40(),
    2647
            drawnIndex: assetData.drawnIndex,
    2648
            drawnRate: assetData.drawnRate
    2649
          });
    2650
      }
    2651
    2652
      function getSpokePosition(
    2653
        ISpoke spoke,
    2654
        function(ISpoke) internal view returns (uint256) reserveIdFn
    2655
      ) internal view returns (SpokePosition memory) {
    2656
        return getSpokePosition(spoke, reserveIdFn(spoke));
    2657
      }
    2658
    2659
      function getSpokePosition(
    2660
        ISpoke spoke,
    2661
        uint256 reserveId
    2662
      ) internal view returns (SpokePosition memory) {
    2663
        uint256 assetId = spoke.getReserve(reserveId).assetId;
    2664
        IHub.SpokeData memory spokeData = hub1.getSpoke(assetId, address(spoke));
    2665
        (uint256 drawn, uint256 premium) = hub1.getSpokeOwed(assetId, address(spoke));
    2666
        return
    2667
          SpokePosition({
    2668
            reserveId: reserveId,
    2669
            assetId: assetId,
    2670
            addedShares: spokeData.addedShares,
    2671
            addedAmount: hub1.getSpokeAddedAssets(assetId, address(spoke)),
    2672
            drawnShares: spokeData.drawnShares,
    2673
            drawn: drawn,
    2674
            premiumShares: spokeData.premiumShares,
    2675
            premiumOffsetRay: spokeData.premiumOffsetRay,
    2676
            premium: premium
    2677
          });
    2678
      }
    2679
    2680
      function _getReserve(ISpoke spoke, uint256 reserveId) internal view returns (Reserve memory) {
    2681
        ISpoke.Reserve memory reserve = spoke.getReserve(reserveId);
    2682
        return
    2683
          Reserve({
    2684
            reserveId: reserveId,
    2685
            hub: _hub(spoke, reserveId),
    2686
            assetId: reserve.assetId,
    2687
            decimals: reserve.decimals,
    2688
            dynamicConfigKey: reserve.dynamicConfigKey,
    2689
            paused: reserve.flags.paused(),
    2690
            frozen: reserve.flags.frozen(),
    2691
            borrowable: reserve.flags.borrowable(),
    2692
            receiveSharesEnabled: reserve.flags.receiveSharesEnabled(),
    2693
            collateralRisk: reserve.collateralRisk
    2694
          });
    2695
      }
    2696
    2697
      function assertEq(SpokePosition memory a, AssetPosition memory b) internal pure {
    2698
        assertEq(a.assetId, b.assetId, 'assetId');
    2699
        assertEq(a.addedShares, b.addedShares, 'addedShares');
    2700
        assertEq(a.addedAmount, b.addedAmount, 'addedAmount');
    2701
        assertEq(a.drawnShares, b.drawnShares, 'drawnShares');
    2702
        assertEq(a.drawn, b.drawn, 'drawnDebt');
    2703
        assertEq(a.premiumShares, b.premiumShares, 'premiumShares');
    2704
        assertEq(a.premiumOffsetRay, b.premiumOffsetRay, 'premiumOffsetRay');
    2705
        assertEq(a.premium, b.premium, 'premium');
    2706
      }
    2707
    2708
      function assertEq(SpokePosition memory a, SpokePosition memory b) internal pure {
    2709
        assertEq(a.reserveId, b.reserveId, 'reserveId');
    2710
        assertEq(a.assetId, b.assetId, 'assetId');
    2711
        assertEq(a.addedShares, b.addedShares, 'addedShares');
    2712
        assertEq(a.addedAmount, b.addedAmount, 'addedAmount');
    2713
        assertEq(a.drawnShares, b.drawnShares, 'drawnShares');
    2714
        assertEq(a.drawn, b.drawn, 'drawn');
    2715
        assertEq(a.premiumShares, b.premiumShares, 'premiumShares');
    2716
        assertEq(a.premiumOffsetRay, b.premiumOffsetRay, 'premiumOffsetRay');
    2717
        assertEq(a.premium, b.premium, 'premium');
    2718
        assertEq(abi.encode(a), abi.encode(b)); // sanity check
    2719
      }
    2720
    2721
      modifier pausePrank() {
    2722
        (VmSafe.CallerMode callerMode, address msgSender, address txOrigin) = vm.readCallers();
    2723
        if (callerMode == VmSafe.CallerMode.RecurrentPrank) vm.stopPrank();
    2724
        _;
    2725
        if (callerMode == VmSafe.CallerMode.RecurrentPrank) vm.startPrank(msgSender, txOrigin);
    2726
      }
    2727
    2728
      function makeEntity(string memory id, bytes32 key) internal returns (address) {
    2729
        return makeAddr(string.concat(id, '-', vm.toString(uint256(key))));
    2730
      }
    2731
    2732
      function makeUser(uint256 i) internal returns (address) {
    2733
        return makeEntity('user', bytes32(i));
    2734
      }
    2735
    2736
      function makeUser() internal returns (address) {
    2737
        return makeEntity('user', vm.randomBytes8());
    2738
      }
    2739
    2740
      function makeSpoke() internal returns (address) {
    2741
        return makeEntity('spoke', vm.randomBytes8());
    2742
      }
    2743
    2744
      function _getTypedDataHash(
    2745
        TestnetERC20 token,
    2746
        EIP712Types.Permit memory permit
    2747
      ) internal view returns (bytes32) {
    2748
        return
    2749
          keccak256(
    2750
            abi.encodePacked(
    2751
              '\x19\x01',
    2752
              token.DOMAIN_SEPARATOR(),
    2753
              vm.eip712HashStruct('Permit', abi.encode(permit))
    2754
            )
    2755
          );
    2756
      }
    2757
    2758
      function _getTypedDataHash(
    2759
        ISpoke spoke,
    2760
        EIP712Types.SetUserPositionManager memory setUserPositionManager
    2761
      ) internal view returns (bytes32) {
    2762
        return
    2763
          keccak256(
    2764
            abi.encodePacked(
    2765
              '\x19\x01',
    2766
              spoke.DOMAIN_SEPARATOR(),
    2767
              vm.eip712HashStruct('SetUserPositionManager', abi.encode(setUserPositionManager))
    2768
            )
    2769
          );
    2770
      }
    2771
    2772
      /**
    2773
       * @dev Warps after to a random time after a randomly generated deadline.
    2774
       * @return The randomly generated deadline.
    2775
       */
    2776
      function _warpAfterRandomDeadline() internal returns (uint256) {
    2777
        uint256 deadline = vm.randomUint(0, MAX_SKIP_TIME - 1);
    2778
        vm.warp(vm.randomUint(deadline + 1, MAX_SKIP_TIME));
    2779
        return deadline;
    2780
      }
    2781
    2782
      /**
    2783
       * @dev Warps to a random time before a randomly generated deadline.
    2784
       * @return The randomly generated deadline.
    2785
       */
    2786
      function _warpBeforeRandomDeadline() internal returns (uint256) {
    2787
        uint256 deadline = vm.randomUint(1, MAX_SKIP_TIME);
    2788
        vm.warp(vm.randomUint(0, deadline - 1));
    2789
        return deadline;
    2790
      }
    2791
    2792
      /**
    2793
       * @dev Burns random nonces from 1 at the specified key lifetime.
    2794
       */
    2795
      function _burnRandomNoncesAtKey(
    2796
        INoncesKeyed verifier,
    2797
        address user,
    2798
        uint192 key
    2799
      ) internal returns (uint256) {
    2800
        uint256 currentKeyNonce = verifier.nonces(user, key);
    2801
        (, uint64 nonce) = _unpackNonce(currentKeyNonce);
    2802
    2803
        uint64 toBurn = vm.randomUint(1, 100).toUint64();
    2804
        for (uint256 i; i < toBurn; ++i) {
    2805
          vm.prank(user);
    2806
          verifier.useNonce(key);
    2807
        }
    2808
        uint256 newKeyNonce = _packNonce(key, nonce + toBurn);
    2809
    2810
        // doesn't work because of the assumption in StdStorage.checkSlotMutatesCall :(
    2811
        // stdstore
    2812
        //   .target(verifier)
    2813
        //   .sig(INoncesKeyed.nonces.selector)
    2814
        //   .with_key(user)
    2815
        //   .with_key(key)
    2816
        //   .checked_write(newNonce);
    2817
    2818
        assertEq(verifier.nonces(user, key), newKeyNonce);
    2819
        return newKeyNonce;
    2820
      }
    2821
    2822
      function _burnRandomNoncesAtKey(INoncesKeyed verifier, address user) internal returns (uint256) {
    2823
        return _burnRandomNoncesAtKey(verifier, user, _randomNonceKey());
    2824
      }
    2825
    2826
      function _getRandomInvalidNonceAtKey(
    2827
        INoncesKeyed verifier,
    2828
        address user,
    2829
        uint192 key
    2830
      ) internal returns (uint256) {
    2831
        (uint192 currentKey, uint64 currentNonce) = _unpackNonce(verifier.nonces(user, key));
    2832
        assertEq(currentKey, key);
    2833
        uint64 nonce = _randomNonce();
    2834
        while (currentNonce == nonce) nonce = _randomNonce();
    2835
        return _packNonce(key, nonce);
    2836
      }
    2837
    2838
      function _assertNonceIncrement(
    2839
        INoncesKeyed verifier,
    2840
        address who,
    2841
        uint256 prevKeyNonce
    2842
      ) internal view {
    2843
        (uint192 nonceKey, uint64 nonce) = _unpackNonce(prevKeyNonce);
    2844
        // prettier-ignore
    2845
        unchecked { ++nonce; }
    2846
        assertEq(verifier.nonces(who, nonceKey), _packNonce(nonceKey, nonce));
    2847
      }
    2848
    2849
      /// @dev Pack key and nonce into a keyNonce
    2850
      function _packNonce(uint192 key, uint64 nonce) internal pure returns (uint256) {
    2851
        return (uint256(key) << 64) | nonce;
    2852
      }
    2853
    2854
      /// @dev Unpack a keyNonce into its key and nonce components
    2855
      function _unpackNonce(uint256 keyNonce) internal pure returns (uint192 key, uint64 nonce) {
    2856
        return (uint192(keyNonce >> 64), uint64(keyNonce));
    2857
      }
    2858
    2859
      function _bpsToRay(uint256 bps) internal pure returns (uint256) {
    2860
        return (bps * WadRayMath.RAY) / PercentageMath.PERCENTAGE_FACTOR;
    2861
      }
    2862
    2863
      /// @dev Calculate expected fees based on previous drawn index
    2864
      function _calcUnrealizedFees(IHub hub, uint256 assetId) internal view returns (uint256) {
    2865
        IHub.Asset memory asset = hub.getAsset(assetId);
    2866
        uint256 previousIndex = asset.drawnIndex;
    2867
        uint256 drawnIndex = asset.drawnIndex.rayMulUp(
    2868
          MathUtils.calculateLinearInterest(asset.drawnRate, uint40(asset.lastUpdateTimestamp))
    2869
        );
    2870
    2871
        uint256 aggregatedOwedRayAfter = (((uint256(asset.drawnShares) + asset.premiumShares) *
    2872
          drawnIndex).toInt256() - asset.premiumOffsetRay).toUint256() + asset.deficitRay;
    2873
        uint256 aggregatedOwedRayBefore = (((uint256(asset.drawnShares) + asset.premiumShares) *
    2874
          previousIndex).toInt256() - asset.premiumOffsetRay).toUint256() + asset.deficitRay;
    2875
    2876
        return
    2877
          (aggregatedOwedRayAfter.fromRayUp() - aggregatedOwedRayBefore.fromRayUp()).percentMulDown(
    2878
            asset.liquidityFee
    2879
          );
    2880
      }
    2881
    2882
      function _getExpectedFeeReceiverAddedAssets(
    2883
        IHub hub,
    2884
        uint256 assetId
    2885
      ) internal view returns (uint256) {
    2886
        uint256 expectedFees = hub.getAsset(assetId).realizedFees + _calcUnrealizedFees(hub, assetId);
    2887
        assertEq(expectedFees, hub.getAssetAccruedFees(assetId), 'asset accrued fees');
    2888
        return hub.getSpokeAddedAssets(assetId, hub.getAsset(assetId).feeReceiver) + expectedFees;
    2889
      }
    2890
    2891
      function _getAddedAssetsWithFees(IHub hub, uint256 assetId) internal view returns (uint256) {
    2892
        return
    2893
          hub.getAddedAssets(assetId) +
    2894
          hub.getAsset(assetId).realizedFees +
    2895
          _calcUnrealizedFees(hub, assetId);
    2896
      }
    2897
    }
    2898
    15.0% tests/Constants.sol
    Lines covered: 2 / 13 (15.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    library Constants {
    6
      /// @dev Hub Constants
    7
      uint8 public constant MAX_ALLOWED_UNDERLYING_DECIMALS = 18;
    8
      uint8 public constant MIN_ALLOWED_UNDERLYING_DECIMALS = 6;
    9
      uint40 public constant MAX_ALLOWED_SPOKE_CAP = type(uint40).max;
    10
      uint24 public constant MAX_RISK_PREMIUM_THRESHOLD = type(uint24).max; // 167772.15%
    11
    12
      /// @dev Spoke Constants
    13
      uint8 public constant ORACLE_DECIMALS = 8;
    14
      uint64 public constant HEALTH_FACTOR_LIQUIDATION_THRESHOLD = 1e18;
    15
      uint256 public constant DUST_LIQUIDATION_THRESHOLD = 1000e26;
    16
      uint24 public constant MAX_ALLOWED_COLLATERAL_RISK = 1000_00; // 1000.00%
    17
      uint256 public constant MAX_ALLOWED_DYNAMIC_CONFIG_KEY = type(uint24).max;
    18
      bytes32 public constant SET_USER_POSITION_MANAGER_TYPEHASH =
    19
        // keccak256('SetUserPositionManager(address positionManager,address user,bool approve,uint256 nonce,uint256 deadline)')
    20
        0x758d23a3c07218b7ea0b4f7f63903c4e9d5cbde72d3bcfe3e9896639025a0214;
    21
      uint256 public constant MAX_ALLOWED_ASSET_ID = type(uint16).max;
    22
    }
    23
    100.0% tests/Utils.sol
    Lines covered: 1 / 1 (100.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    import {Vm} from 'forge-std/Vm.sol';
    6
    import {IERC20} from 'src/dependencies/openzeppelin/IERC20.sol';
    7
    import {IHub, IHubBase} from 'src/hub/interfaces/IHub.sol';
    8
    import {ISpokeBase, ISpoke} from 'src/spoke/interfaces/ISpoke.sol';
    9
    10
    library Utils {
    11
      Vm internal constant vm = Vm(address(uint160(uint256(keccak256('hevm cheat code')))));
    12
    13
      // hub
    14
      function add(
    15
        IHubBase hub,
    16
        uint256 assetId,
    17
        address caller,
    18
        uint256 amount,
    19
        address user
    20
      ) internal returns (uint256) {
    21
        IHub ihub = IHub(address(hub));
    22
        approve(ihub, assetId, caller, user, amount);
    23
        transferFrom(ihub, assetId, caller, user, address(hub), amount);
    24
        vm.prank(caller);
    25
        return hub.add(assetId, amount);
    26
      }
    27
    28
      function draw(
    29
        IHubBase hub,
    30
        uint256 assetId,
    31
        address caller,
    32
        address to,
    33
        uint256 amount
    34
      ) internal returns (uint256) {
    35
        vm.prank(caller);
    36
        return hub.draw(assetId, amount, to);
    37
      }
    38
    39
      function remove(
    40
        IHubBase hub,
    41
        uint256 assetId,
    42
        address caller,
    43
        uint256 amount,
    44
        address to
    45
      ) internal returns (uint256) {
    46
        vm.prank(caller);
    47
        return hub.remove(assetId, amount, to);
    48
      }
    49
    50
      function restoreDrawn(
    51
        IHubBase hub,
    52
        uint256 assetId,
    53
        address caller,
    54
        uint256 drawnAmount,
    55
        address restorer
    56
      ) internal returns (uint256) {
    57
        IHub ihub = IHub(address(hub));
    58
        approve(ihub, assetId, caller, restorer, drawnAmount);
    59
        transferFrom(ihub, assetId, caller, restorer, address(hub), drawnAmount);
    60
        vm.prank(caller);
    61
        return hub.restore(assetId, drawnAmount, IHubBase.PremiumDelta(0, 0, 0));
    62
      }
    63
    64
      function addSpoke(
    65
        IHub hub,
    66
        address hubAdmin,
    67
        uint256 assetId,
    68
        address spoke,
    69
        IHub.SpokeConfig memory spokeConfig
    70
      ) internal {
    71
        vm.prank(hubAdmin);
    72
        hub.addSpoke(assetId, spoke, spokeConfig);
    73
      }
    74
    75
      function updateSpokeConfig(
    76
        IHub hub,
    77
        address hubAdmin,
    78
        uint256 assetId,
    79
        address spoke,
    80
        IHub.SpokeConfig memory spokeConfig
    81
      ) internal {
    82
        vm.prank(hubAdmin);
    83
        hub.updateSpokeConfig(assetId, spoke, spokeConfig);
    84
      }
    85
    86
      function addAsset(
    87
        IHub hub,
    88
        address hubAdmin,
    89
        address underlying,
    90
        uint8 decimals,
    91
        address feeReceiver,
    92
        address interestRateStrategy,
    93
        bytes memory encodedIrData
    94
      ) internal returns (uint256) {
    95
        vm.prank(hubAdmin);
    96
        return hub.addAsset(underlying, decimals, feeReceiver, interestRateStrategy, encodedIrData);
    97
      }
    98
    99
      function updateAssetConfig(
    100
        IHub hub,
    101
        address hubAdmin,
    102
        uint256 assetId,
    103
        IHub.AssetConfig memory config,
    104
        bytes memory encodedIrData
    105
      ) internal {
    106
        vm.prank(hubAdmin);
    107
        hub.updateAssetConfig(assetId, config, encodedIrData);
    108
      }
    109
    110
      // spoke
    111
      function setUsingAsCollateral(
    112
        ISpoke spoke,
    113
        uint256 reserveId,
    114
        address caller,
    115
        bool usingAsCollateral,
    116
        address onBehalfOf
    117
      ) internal {
    118
        vm.prank(caller);
    119
        spoke.setUsingAsCollateral(reserveId, usingAsCollateral, onBehalfOf);
    120
      }
    121
    122
      function supply(
    123
        ISpokeBase spoke,
    124
        uint256 reserveId,
    125
        address caller,
    126
        uint256 amount,
    127
        address onBehalfOf
    128
      ) internal {
    129
        vm.prank(caller);
    130
        spoke.supply(reserveId, amount, onBehalfOf);
    131
      }
    132
    133
      function supplyCollateral(
    134
        ISpoke spoke,
    135
        uint256 reserveId,
    136
        address caller,
    137
        uint256 amount,
    138
        address onBehalfOf
    139
      ) internal {
    140
        supply(spoke, reserveId, caller, amount, onBehalfOf);
    141
        setUsingAsCollateral(spoke, reserveId, caller, true, onBehalfOf);
    142
      }
    143
    144
      function withdraw(
    145
        ISpokeBase spoke,
    146
        uint256 reserveId,
    147
        address caller,
    148
        uint256 amount,
    149
        address onBehalfOf
    150
      ) internal {
    151
        vm.prank(caller);
    152
        spoke.withdraw(reserveId, amount, onBehalfOf);
    153
      }
    154
    155
      function borrow(
    156
        ISpokeBase spoke,
    157
        uint256 reserveId,
    158
        address caller,
    159
        uint256 amount,
    160
        address onBehalfOf
    161
      ) internal {
    162
        vm.prank(caller);
    163
        spoke.borrow(reserveId, amount, onBehalfOf);
    164
      }
    165
    166
      function repay(
    167
        ISpokeBase spoke,
    168
        uint256 reserveId,
    169
        address caller,
    170
        uint256 amount,
    171
        address onBehalfOf
    172
      ) internal {
    173
        vm.prank(caller);
    174
        spoke.repay(reserveId, amount, onBehalfOf);
    175
      }
    176
    177
      function mintFeeShares(IHub hub, uint256 assetId, address caller) internal returns (uint256) {
    178
        vm.prank(caller);
    179
        return hub.mintFeeShares(assetId);
    180
      }
    181
    182
      function approve(ISpoke spoke, uint256 reserveId, address owner, uint256 amount) internal {
    183
        address underlying = spoke.getReserve(reserveId).underlying;
    184
        _approve(IERC20(underlying), owner, address(spoke), amount);
    185
      }
    186
    187
      function approve(ISpoke spoke, address underlying, address owner, uint256 amount) internal {
    188
        _approve(IERC20(underlying), owner, address(spoke), amount);
    189
      }
    190
    191
      function approve(
    192
        ISpoke spoke,
    193
        uint256 reserveId,
    194
        address owner,
    195
        address spender,
    196
        uint256 amount
    197
      ) internal {
    198
        IHub hub = IHub(address(spoke.getReserve(reserveId).hub));
    199
        _approve(
    200
          IERC20(hub.getAsset(spoke.getReserve(reserveId).assetId).underlying),
    201
          owner,
    202
          spender,
    203
          amount
    204
        );
    205
      }
    206
    207
      function approve(
    208
        IHub hub,
    209
        uint256 assetId,
    210
        address caller,
    211
        address owner,
    212
        uint256 amount
    213
      ) internal {
    214
        /// @dev caller is always a spoke
    215
        _approve(IERC20(hub.getAsset(assetId).underlying), owner, caller, amount);
    216
      }
    217
    218
      function _approve(IERC20 underlying, address owner, address spender, uint256 amount) private {
    219
        vm.startPrank(owner);
    220
        underlying.approve(spender, 0);
    221
        underlying.approve(spender, amount);
    222
        vm.stopPrank();
    223
      }
    224
    225
      function transferFrom(
    226
        ISpoke spoke,
    227
        uint256 reserveId,
    228
        address caller,
    229
        address from,
    230
        address to,
    231
        uint256 amount
    232
      ) internal {
    233
        _transferFrom(IERC20(spoke.getReserve(reserveId).underlying), caller, from, to, amount);
    234
      }
    235
    236
      function transferFrom(
    237
        IHub hub,
    238
        uint256 assetId,
    239
        address caller,
    240
        address from,
    241
        address to,
    242
        uint256 amount
    243
      ) internal {
    244
        _transferFrom(IERC20(hub.getAsset(assetId).underlying), caller, from, to, amount);
    245
      }
    246
    247
      function _transferFrom(
    248
        IERC20 underlying,
    249
        address caller,
    250
        address from,
    251
        address to,
    252
        uint256 amount
    253
      ) private {
    254
        vm.prank(caller);
    255
        underlying.transferFrom(from, to, amount);
    256
      }
    257
    }
    258
    0.0% tests/mocks/GatewayBaseWrapper.sol
    Lines covered: 0 / 2 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity 0.8.28;
    4
    5
    import {GatewayBase} from 'src/position-manager/GatewayBase.sol';
    6
    7
    contract GatewayBaseWrapper is GatewayBase {
    8
      constructor(address initialOwner_) GatewayBase(initialOwner_) {}
    9
    }
    10
    0.0% tests/mocks/MockERC1271Wallet.sol
    Lines covered: 0 / 11 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    import {IERC1271} from 'src/dependencies/openzeppelin/IERC1271.sol';
    6
    7
    contract MockERC1271Wallet is IERC1271 {
    8
      address public owner;
    9
    10
      mapping(bytes32 => bool) public isValidHash;
    11
    12
      error OnlyOwner();
    13
    14
      constructor(address owner_) {
    15
        owner = owner_;
    16
      }
    17
    18
      function approveHash(bytes32 _hash) external {
    19
        if (msg.sender != owner) revert OnlyOwner();
    20
        isValidHash[_hash] = true;
    21
      }
    22
    23
      function isValidSignature(
    24
        bytes32 _hash,
    25
        bytes memory /*_signature*/
    26
      ) public view returns (bytes4) {
    27
        return isValidHash[_hash] ? this.isValidSignature.selector : bytes4(0);
    28
      }
    29
    }
    30
    0.0% tests/mocks/MockERC20.sol
    Lines covered: 0 / 6 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    import {ERC20} from 'src/dependencies/openzeppelin/ERC20.sol';
    6
    7
    contract MockERC20 is ERC20 {
    8
      // TODO: add decimals to constructor to be able to mimic actual tokens, ie USDC has 6 decimals
    9
      constructor() ERC20('MockERC20', 'E20M') {}
    10
    11
      function mint(address account, uint256 amount) external {
    12
        _mint(account, amount);
    13
      }
    14
    15
      function burn(address account, uint256 amount) external {
    16
        _burn(account, amount);
    17
      }
    18
    }
    19
    0.0% tests/mocks/MockNoncesKeyed.sol
    Lines covered: 0 / 3 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.10;
    4
    5
    import {NoncesKeyed} from 'src/utils/NoncesKeyed.sol';
    6
    7
    contract MockNoncesKeyed is NoncesKeyed {
    8
      function useCheckedNonce(address owner, uint256 keyNonce) public {
    9
        _useCheckedNonce(owner, keyNonce);
    10
      }
    11
    }
    12
    66.0% tests/mocks/MockPriceFeed.sol
    Lines covered: 10 / 15 (66.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    import {AggregatorV3Interface} from 'src/dependencies/chainlink/AggregatorV3Interface.sol';
    6
    7
    contract MockPriceFeed is AggregatorV3Interface {
    8
      uint8 public immutable override decimals;
    9
      string public override description;
    10
    11
      int256 private immutable _price;
    12
    13
      error OperationNotSupported();
    14
    15
      constructor(uint8 decimals_, string memory description_, uint256 price_) {
    16
        decimals = decimals_;
    17
        description = description_;
    18
        _price = int256(price_);
    19
      }
    20
    21
      function version() external pure override returns (uint256) {
    22
        return 1;
    23
      }
    24
    25
      function getRoundData(
    26
        uint80
    27
      ) external pure override returns (uint80, int256, uint256, uint256, uint80) {
    28
        revert OperationNotSupported();
    29
      }
    30
    31
      function latestRoundData()
    32
        external
    33
        view
    34
        virtual
    35
        override
    36
        returns (
    37
          uint80 roundId,
    38
          int256 answer,
    39
          uint256 startedAt,
    40
          uint256 updatedAt,
    41
          uint80 answeredInRound
    42
        )
    43
      {
    44
        roundId = uint80(block.timestamp);
    45
        answer = _price;
    46
        startedAt = block.timestamp;
    47
        updatedAt = block.timestamp;
    48
        answeredInRound = roundId;
    49
      }
    50
    }
    51
    0.0% tests/mocks/MockSkimSpoke.sol
    Lines covered: 0 / 12 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    import {IHubBase} from 'src/hub/interfaces/IHubBase.sol';
    6
    7
    contract MockSkimSpoke {
    8
      IHubBase public immutable HUB;
    9
    10
      constructor(address hub_) {
    11
        HUB = IHubBase(hub_);
    12
      }
    13
    14
      function skimAdd(uint256 assetId, uint256 amount) external returns (uint256) {
    15
        return HUB.add(assetId, amount);
    16
      }
    17
    18
      function withdraw(uint256 assetId, uint256 amount, address to) external returns (uint256) {
    19
        return HUB.remove(assetId, amount, to);
    20
      }
    21
    22
      function draw(uint256 assetId, uint256 amount, address to) external returns (uint256) {
    23
        return HUB.draw(assetId, amount, to);
    24
      }
    25
    26
      function skimRestore(uint256 assetId, uint256 drawnAmount) external returns (uint256) {
    27
        return HUB.restore(assetId, drawnAmount, IHubBase.PremiumDelta(0, 0, 0));
    28
      }
    29
    }
    30
    0.0% tests/mocks/MockSpoke.sol
    Lines covered: 0 / 48 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    import {Spoke, ISpoke, IHubBase, SafeCast, PositionStatusMap} from 'src/spoke/Spoke.sol';
    6
    import {WadRayMath} from 'src/libraries/math/WadRayMath.sol';
    7
    import {Test} from 'forge-std/Test.sol';
    8
    9
    /// @dev inherit from Test to exclude contract from forge size check
    10
    contract MockSpoke is Spoke, Test {
    11
      using SafeCast for *;
    12
      using PositionStatusMap for *;
    13
    14
      // Data structure to mock the user account data
    15
      struct AccountDataInfo {
    16
        uint256[] collateralReserveIds;
    17
        uint256[] collateralAmounts;
    18
        uint256[] collateralDynamicConfigKeys;
    19
        uint256[] suppliedAssetsReserveIds;
    20
        uint256[] suppliedAssetsAmounts;
    21
        uint256[] debtReserveIds;
    22
        uint256[] drawnDebtAmounts;
    23
        uint256[] realizedPremiumAmountsRay;
    24
        uint256[] accruedPremiumAmounts;
    25
      }
    26
    27
      constructor(address oracle_) Spoke(oracle_) {}
    28
    29
      function initialize(address) external override {}
    30
    31
      // same as spoke's borrow, but without health factor check
    32
      function borrowWithoutHfCheck(
    33
        uint256 reserveId,
    34
        uint256 amount,
    35
        address onBehalfOf
    36
      ) external onlyPositionManager(onBehalfOf) {
    37
        Reserve storage reserve = _reserves[reserveId];
    38
        UserPosition storage userPosition = _userPositions[onBehalfOf][reserveId];
    39
        PositionStatus storage positionStatus = _positionStatus[onBehalfOf];
    40
        uint256 assetId = reserve.assetId;
    41
        IHubBase hub = reserve.hub;
    42
    43
        uint256 drawnShares = hub.draw(assetId, amount, msg.sender);
    44
    45
        userPosition.drawnShares += drawnShares.toUint120();
    46
        positionStatus.setBorrowing(reserveId, true);
    47
    48
        ISpoke.UserAccountData memory userAccountData = _processUserAccountData(onBehalfOf, true);
    49
        _notifyRiskPremiumUpdate(onBehalfOf, userAccountData.riskPremium);
    50
    51
        emit Borrow(reserveId, msg.sender, onBehalfOf, drawnShares, amount);
    52
      }
    53
    54
      // Mock the user account data
    55
      function mockStorage(address user, AccountDataInfo memory info) external {
    56
        PositionStatus storage positionStatus = _positionStatus[user];
    57
        for (uint256 i = 0; i < info.collateralReserveIds.length; i++) {
    58
          positionStatus.setUsingAsCollateral(info.collateralReserveIds[i], true);
    59
          Reserve storage reserve = _reserves[info.collateralReserveIds[i]];
    60
          _userPositions[user][info.collateralReserveIds[i]].suppliedShares = reserve
    61
            .hub
    62
            .previewAddByAssets(reserve.assetId, info.collateralAmounts[i])
    63
            .toUint120();
    64
    65
          _userPositions[user][info.collateralReserveIds[i]].dynamicConfigKey = info
    66
            .collateralDynamicConfigKeys[i]
    67
            .toUint16();
    68
        }
    69
    70
        for (uint256 i = 0; i < info.suppliedAssetsReserveIds.length; i++) {
    71
          Reserve storage reserve = _reserves[info.suppliedAssetsReserveIds[i]];
    72
          _userPositions[user][info.suppliedAssetsReserveIds[i]].suppliedShares = reserve
    73
            .hub
    74
            .previewAddByAssets(reserve.assetId, info.suppliedAssetsAmounts[i])
    75
            .toUint120();
    76
        }
    77
    78
        for (uint256 i = 0; i < info.debtReserveIds.length; i++) {
    79
          positionStatus.setBorrowing(info.debtReserveIds[i], true);
    80
          Reserve storage reserve = _reserves[info.debtReserveIds[i]];
    81
          _userPositions[user][info.debtReserveIds[i]].drawnShares = reserve
    82
            .hub
    83
            .previewDrawByAssets(reserve.assetId, info.drawnDebtAmounts[i])
    84
            .toUint120();
    85
          _userPositions[user][info.debtReserveIds[i]].premiumShares = vm
    86
            .randomUint(
    87
              reserve.hub.previewRemoveByAssets(reserve.assetId, info.accruedPremiumAmounts[i]),
    88
              100e18
    89
            )
    90
            .toUint120();
    91
          _userPositions[user][info.debtReserveIds[i]].premiumOffsetRay =
    92
            (_userPositions[user][info.debtReserveIds[i]].premiumShares *
    93
              reserve.hub.getAssetDrawnIndex(reserve.assetId)).toInt256().toInt200() -
    94
            (info.accruedPremiumAmounts[i] * WadRayMath.RAY).toInt256().toInt200() -
    95
            (info.realizedPremiumAmountsRay[i]).toInt256().toInt200();
    96
        }
    97
      }
    98
    99
      // Exposes spoke's calculateUserAccountData
    100
      function calculateUserAccountData(
    101
        address user,
    102
        bool refreshConfig
    103
      ) external returns (UserAccountData memory) {
    104
        return _processUserAccountData(user, refreshConfig);
    105
      }
    106
    107
      function getRiskPremium(address user) external view returns (uint24) {
    108
        return _positionStatus[user].riskPremium;
    109
      }
    110
    111
      function setReserveDynamicConfigKey(uint256 reserveId, uint24 configKey) external {
    112
        _reserves[reserveId].dynamicConfigKey = configKey;
    113
      }
    114
    }
    115
    0.0% tests/mocks/MockSpokeInstance.sol
    Lines covered: 0 / 13 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    import {Spoke} from 'src/spoke/Spoke.sol';
    6
    7
    contract MockSpokeInstance is Spoke {
    8
      bool public constant IS_TEST = true;
    9
    10
      uint64 public immutable SPOKE_REVISION;
    11
    12
      /**
    13
       * @dev Constructor.
    14
       * @dev It sets the spoke revision and disables the initializers.
    15
       * @param spokeRevision_ The revision of the spoke contract.
    16
       * @param oracle_ The address of the oracle.
    17
       */
    18
      constructor(uint64 spokeRevision_, address oracle_) Spoke(oracle_) {
    19
        SPOKE_REVISION = spokeRevision_;
    20
        _disableInitializers();
    21
      }
    22
    23
      /// @inheritdoc Spoke
    24
      function initialize(address _authority) external override reinitializer(SPOKE_REVISION) {
    25
        emit UpdateOracle(ORACLE);
    26
        require(_authority != address(0), InvalidAddress());
    27
        __AccessManaged_init(_authority);
    28
        if (_liquidationConfig.targetHealthFactor == 0) {
    29
          _liquidationConfig.targetHealthFactor = HEALTH_FACTOR_LIQUIDATION_THRESHOLD;
    30
          emit UpdateLiquidationConfig(_liquidationConfig);
    31
        }
    32
      }
    33
    }
    34
    0.0% tests/mocks/PositionStatusMapWrapper.sol
    Lines covered: 0 / 40 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    import {PositionStatusMap} from 'src/spoke/libraries/PositionStatusMap.sol';
    6
    import {ISpoke} from 'src/spoke/interfaces/ISpoke.sol';
    7
    8
    contract PositionStatusMapWrapper {
    9
      using PositionStatusMap for ISpoke.PositionStatus;
    10
    11
      ISpoke.PositionStatus internal _p;
    12
    13
      function BORROWING_MASK() external pure returns (uint256) {
    14
        return PositionStatusMap.BORROWING_MASK;
    15
      }
    16
    17
      function COLLATERAL_MASK() external pure returns (uint256) {
    18
        return PositionStatusMap.COLLATERAL_MASK;
    19
      }
    20
    21
      function setBorrowing(uint256 reserveId, bool borrowing) external {
    22
        _p.setBorrowing(reserveId, borrowing);
    23
      }
    24
    25
      function setUsingAsCollateral(uint256 reserveId, bool usingAsCollateral) external {
    26
        _p.setUsingAsCollateral(reserveId, usingAsCollateral);
    27
      }
    28
    29
      function isUsingAsCollateralOrBorrowing(uint256 reserveId) external view returns (bool) {
    30
        return _p.isUsingAsCollateralOrBorrowing(reserveId);
    31
      }
    32
    33
      function isBorrowing(uint256 reserveId) external view returns (bool) {
    34
        return _p.isBorrowing(reserveId);
    35
      }
    36
    37
      function isUsingAsCollateral(uint256 reserveId) external view returns (bool) {
    38
        return _p.isUsingAsCollateral(reserveId);
    39
      }
    40
    41
      function collateralCount(uint256 reserveCount) external view returns (uint256) {
    42
        return _p.collateralCount(reserveCount);
    43
      }
    44
    45
      function getBucketWord(uint256 reserveId) external view returns (uint256) {
    46
        return _p.getBucketWord(reserveId);
    47
      }
    48
    49
      function bucketId(uint256 reserveId) external pure returns (uint256) {
    50
        return PositionStatusMap.bucketId(reserveId);
    51
      }
    52
    53
      function fromBitId(uint256 bitId, uint256 bucket) external pure returns (uint256) {
    54
        return PositionStatusMap.fromBitId(bitId, bucket);
    55
      }
    56
    57
      function isolateBorrowing(uint256 word) external pure returns (uint256) {
    58
        return PositionStatusMap.isolateBorrowing(word);
    59
      }
    60
    61
      function isolateBorrowingUntil(
    62
        uint256 word,
    63
        uint256 reserveCount
    64
      ) external pure returns (uint256) {
    65
        return PositionStatusMap.isolateBorrowingUntil(word, reserveCount);
    66
      }
    67
    68
      function isolateUntil(uint256 word, uint256 reserveId) external pure returns (uint256) {
    69
        return PositionStatusMap.isolateUntil(word, reserveId);
    70
      }
    71
    72
      function isolateCollateral(uint256 word) external pure returns (uint256) {
    73
        return PositionStatusMap.isolateCollateral(word);
    74
      }
    75
    76
      function isolateCollateralUntil(
    77
        uint256 word,
    78
        uint256 reserveCount
    79
      ) external pure returns (uint256) {
    80
        return PositionStatusMap.isolateCollateralUntil(word, reserveCount);
    81
      }
    82
    83
      function next(uint256 startReserveId) external view returns (uint256, bool, bool) {
    84
        return _p.next(startReserveId);
    85
      }
    86
    87
      function nextBorrowing(uint256 startReserveId) external view returns (uint256) {
    88
        return _p.nextBorrowing(startReserveId);
    89
      }
    90
    91
      function nextCollateral(uint256 startReserveId) external view returns (uint256) {
    92
        return _p.nextCollateral(startReserveId);
    93
      }
    94
    95
      function slot() external pure returns (bytes32 s) {
    96
        assembly ('memory-safe') {
    97
          s := _p.slot
    98
        }
    99
      }
    100
    }
    101
    0.0% tests/mocks/RescuableWrapper.sol
    Lines covered: 0 / 5 (0.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    import {Rescuable} from 'src/utils/Rescuable.sol';
    6
    7
    contract RescuableWrapper is Rescuable {
    8
      address admin;
    9
    10
      constructor(address admin_) {
    11
        admin = admin_;
    12
      }
    13
    14
      function _rescueGuardian() internal view override returns (address) {
    15
        return admin;
    16
      }
    17
    }
    18
    47.0% tests/mocks/TestnetERC20.sol
    Lines covered: 17 / 36 (47.0%)
    1
    // SPDX-License-Identifier: UNLICENSED
    2
    // Copyright (c) 2025 Aave Labs
    3
    pragma solidity ^0.8.0;
    4
    5
    import {ERC20} from 'src/dependencies/openzeppelin/ERC20.sol';
    6
    import {IERC20Permit} from 'src/dependencies/openzeppelin/IERC20Permit.sol';
    7
    8
    /**
    9
     * @title TestnetERC20
    10
     * @dev ERC20 minting logic
    11
     */
    12
    contract TestnetERC20 is IERC20Permit, ERC20 {
    13
      bytes public constant EIP712_REVISION = bytes('1');
    14
      bytes32 internal constant EIP712_DOMAIN =
    15
        keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)');
    16
      bytes32 public constant PERMIT_TYPEHASH =
    17
        keccak256('Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)');
    18
    19
      // Map of address nonces (address => nonce)
    20
      mapping(address => uint256) internal _nonces;
    21
    22
      bytes32 public DOMAIN_SEPARATOR;
    23
    24
      uint8 private _decimals;
    25
    26
      constructor(string memory name_, string memory symbol_, uint8 decimals_) ERC20(name_, symbol_) {
    27
        uint256 chainId = block.chainid;
    28
    29
        DOMAIN_SEPARATOR = keccak256(
    30
          abi.encode(
    31
            EIP712_DOMAIN,
    32
            keccak256(bytes(name_)),
    33
            keccak256(EIP712_REVISION),
    34
            chainId,
    35
            address(this)
    36
          )
    37
        );
    38
        _setupDecimals(decimals_);
    39
      }
    40
    41
      /// @inheritdoc IERC20Permit
    42
      function permit(
    43
        address owner,
    44
        address spender,
    45
        uint256 value,
    46
        uint256 deadline,
    47
        uint8 v,
    48
        bytes32 r,
    49
        bytes32 s
    50
      ) external override {
    51
        require(owner != address(0), 'INVALID_OWNER');
    52
        //solium-disable-next-line
    53
        require(block.timestamp <= deadline, 'INVALID_EXPIRATION');
    54
        uint256 currentValidNonce = _nonces[owner];
    55
        bytes32 digest = keccak256(
    56
          abi.encodePacked(
    57
            '\x19\x01',
    58
            DOMAIN_SEPARATOR,
    59
            keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, currentValidNonce, deadline))
    60
          )
    61
        );
    62
        require(owner == ecrecover(digest, v, r, s), 'INVALID_SIGNATURE');
    63
        _nonces[owner] = currentValidNonce + 1;
    64
        _approve(owner, spender, value);
    65
      }
    66
    67
      /**
    68
       * @dev Function to mint tokens
    69
       * @param value The amount of tokens to mint.
    70
       * @return A boolean that indicates if the operation was successful.
    71
       */
    72
      function mint(uint256 value) public virtual returns (bool) {
    73
        _mint(_msgSender(), value);
    74
        return true;
    75
      }
    76
    77
      /**
    78
       * @dev Function to mint tokens to address
    79
       * @param account The account to mint tokens.
    80
       * @param value The amount of tokens to mint.
    81
       * @return A boolean that indicates if the operation was successful.
    82
       */
    83
      function mint(address account, uint256 value) public virtual returns (bool) {
    84
        _mint(account, value);
    85
        return true;
    86
      }
    87
    88
      function nonces(address owner) public view returns (uint256) {
    89
        return _nonces[owner];
    90
      }
    91
    92
      function decimals() public view virtual override returns (uint8) {
    93
        return _decimals;
    94
      }
    95
    96
      /**
    97
       * @dev Sets {decimals} to a value other than the default one of 18.
    98
       *
    99
       * WARNING: This function should only be called from the constructor. Most
    100
       * applications that interact with token contracts will not expect
    101
       * {decimals} to ever change, and may work incorrectly if it does.
    102
       */
    103
      function _setupDecimals(uint8 decimals_) internal {
    104
        _decimals = decimals_;
    105
      }
    106
    }
    107
    100.0% tests/recon/BeforeAfter.sol
    Lines covered: 32 / 32 (100.0%)
    1
    // SPDX-License-Identifier: GPL-2.0
    2
    pragma solidity ^0.8.0;
    3
    4
    import {Setup} from "./Setup.sol";
    5
    import {ISpoke} from "src/spoke/interfaces/ISpoke.sol";
    6
    import {LiquidationLogic} from "src/spoke/libraries/LiquidationLogic.sol";
    7
    8
    9
    // ghost variables for tracking state variable values before and after function calls
    10
    abstract contract BeforeAfter is Setup {
    11
        enum Operation {
    12
            None,
    13
            SetPrice
    14
        }
    15
    16
        struct Vars {
    17
            bool isAnyUserLiquidatable;
    18
            Operation operation;
    19
        }
    20
    21
        Vars internal _before;
    22
        Vars internal _after;
    23
    24
        mapping(uint256 assetId => uint256 maxDrawnIndexSeen) internal ghost_maxDrawnIndexSeen;
    25
        mapping(uint256 assetId => uint256 maxSupplySharePriceAssetsSeen) internal ghost_maxSupplySharePriceAssetsSeen;
    26
        mapping(uint256 assetId => uint256 maxSupplySharePriceSharesSeen) internal ghost_maxSupplySharePriceSharesSeen;
    27
    28
        /// === MODIFIERS === ///
    29
        /// Prank admin and actor
    30
        
    31
        modifier asAdmin {
    32
            vm.startPrank(ADMIN);
    33
            __before();
    34
            _;
    35
            __after();
    36
            vm.stopPrank();
    37
        }
    38
    39
        modifier asActor {
    40
            vm.startPrank(address(_getActor()));
    41
            __before();
    42
            _;
    43
            __after();
    44
            vm.stopPrank();
    45
        }
    46
    47
        function __before() internal {
    48
            __snapshot(_before);
    49
        }
    50
    51
        function __after() internal {
    52
            __snapshot(_after);
    53
        }
    54
    55
        function __snapshot(Vars storage vars) internal {
    56
            vars.isAnyUserLiquidatable = false;
    57
            vars.operation = Operation.None;
    58
    59
            address[] memory actors = _getActors();
    60
            for(uint256 i = 0; i < actors.length; i++) {
    61
                address actor = actors[i];
    62
                ISpoke.UserAccountData memory actorAccountData = iSpoke.getUserAccountData(actor);
    63
                vars.isAnyUserLiquidatable = vars.isAnyUserLiquidatable || (actorAccountData.healthFactor < LiquidationLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD);
    64
            }
    65
        }
    66
    67
        function _updateMonotonicGhosts(uint256 assetId) internal {
    68
            uint256 currentDrawnIndex = iHub.getAssetDrawnIndex(assetId);
    69
            if (currentDrawnIndex > ghost_maxDrawnIndexSeen[assetId]) {
    70
                ghost_maxDrawnIndexSeen[assetId] = currentDrawnIndex;
    71
            }
    72
    73
            uint256 addedShares = iHub.getAddedShares(assetId);
    74
            if (addedShares > 0) {
    75
                uint256 addedAssets = iHub.getAddedAssets(assetId);
    76
                uint256 maxAssets = ghost_maxSupplySharePriceAssetsSeen[assetId];
    77
                uint256 maxShares = ghost_maxSupplySharePriceSharesSeen[assetId];
    78
                if (maxShares == 0 || maxAssets * addedShares <= addedAssets * maxShares) {
    79
                    ghost_maxSupplySharePriceAssetsSeen[assetId] = addedAssets;
    80
                    ghost_maxSupplySharePriceSharesSeen[assetId] = addedShares;
    81
                }
    82
            }
    83
        }
    84
    }
    100.0% tests/recon/CryticTester.sol
    Lines covered: 2 / 2 (100.0%)
    1
    // SPDX-License-Identifier: GPL-2.0
    2
    pragma solidity ^0.8.0;
    3
    4
    import {CryticAsserts} from "@chimera/CryticAsserts.sol";
    5
    6
    import {TargetFunctions} from "./TargetFunctions.sol";
    7
    8
    // echidna tests/recon/CryticTester.sol --contract CryticTester --config echidna.yaml --format text --workers 32 --test-limit 1000000000
    9
    // medusa fuzz
    10
    contract CryticTester is TargetFunctions, CryticAsserts {
    11
        constructor() payable {
    12
            setup();
    13
        }
    14
    }
    97.0% tests/recon/Properties.sol
    Lines covered: 140 / 144 (97.0%)
    1
    // SPDX-License-Identifier: GPL-2.0
    2
    pragma solidity ^0.8.0;
    3
    4
    import {Asserts} from "@chimera/Asserts.sol";
    5
    import {BeforeAfter} from "./BeforeAfter.sol";
    6
    7
    /// @notice Invariants are written to support both Echidna property mode (bool) and optimization mode (int256).
    8
    /// @dev Default is property mode; to switch, run:
    9
    ///      `sed -i '' -e 's/OPTIMIZATION_MODE = false/OPTIMIZATION_MODE = true/' -e 's/public returns (bool)/public returns (int256 maxViolation)/g' -e 's/return maxViolation <= 0;/return maxViolation;/g' tests/recon/Properties.sol`
    10
    ///      This keeps the same invariant logic but changes the return type and value so fuzzers can optimize on a
    11
    ///      signed percentage target where <= 0 is success and > 0 is a violation, while skipping assertions.
    12
    abstract contract Properties is BeforeAfter, Asserts {
    13
        int256 internal constant PERCENT = int256(1e18);
    14
        bool internal constant OPTIMIZATION_MODE = false;
    15
    16
        /// @dev Avoids Low likelihood scenarios in Audit Contest
    17
        uint256 internal constant MIN_TOTAL_SUPPLIED = 1e6;
    18
    19
        string constant ASSERTION_LIQUIDATION_CALL_DOS = "!!! iSpoke_liquidationCall DoS";
    20
        string constant ASSERTION_REPAY_DOS = "!!! iSpoke_repay DoS";
    21
        string constant ASSERTION_SUPPLY_DOS = "!!! iSpoke_supply DoS";
    22
        string constant ASSERTION_WITHDRAW_DOS = "!!! iSpoke_withdraw DoS";
    23
        string constant ASSERTION_MINT_FEE_SHARES_PPS_CHANGE = "!!! iHub_mintFeeShares PPS change";
    24
        string constant ASSERTION_CANARY = "!!! canary assertion";
    25
    26
        /// @dev Avoids invalidated issues by only implementing pre-vetted list of Audit Contest invariants
    27
        /// @dev Reference https://audits.sherlock.xyz/contests/1209
    28
        string constant INVARIANT_1_TOTAL_BORROWED_LESS_THAN_SUPPLIED_V0 =
    29
            "Invariant 1: Total borrowed assets <= total supplied assets (v0)";
    30
        string constant INVARIANT_1_TOTAL_BORROWED_LESS_THAN_SUPPLIED_V1 =
    31
            "Invariant 1: Total borrowed assets <= total supplied assets (v1)";
    32
        string constant INVARIANT_1_TOTAL_BORROWED_LESS_THAN_SUPPLIED_V2 =
    33
            "Invariant 1: Total borrowed assets <= total supplied assets (v2)";
    34
        string constant INVARIANT_2_TOTAL_BORROWED_SHARES_MATCHES_SPOKE_SUM =
    35
            "Invariant 2: Total borrowed shares == sum of Spoke debt shares";
    36
        string constant INVARIANT_3_HUB_ADDED_ASSETS_GREATER_THAN_SPOKE_SUM =
    37
            "Invariant 3: Hub added assets >= sum of Spoke added assets (converted from shares)";
    38
        string constant INVARIANT_4_HUB_ADDED_SHARES_MATCHES_SPOKE_SUM =
    39
            "Invariant 4: Hub added shares == sum of Spoke added shares";
    40
        string constant INVARIANT_5_SUPPLY_SHARE_PRICE_AND_DRAWN_INDEX_MONOTONIC =
    41
            "Invariant 5: Supply share price and drawn index cannot decrease";
    42
    43
        /// @dev Add extra 'Holy grail' property
    44
        string constant INVARIANT_HOLY_GRAIL_SHOULD_NOT_BECOME_LIQUIDATABLE =
    45
            "Holy grail: Users should not become liquidatable except by price change";
    46
        string constant INVARIANT_CANARY_GLOBAL_INVARIANT_FAILURE = "Canary invariant";
    47
    48
        function _relativeDiff(int256 diff, uint256 denom) internal pure returns (int256) {
    49
            if (denom == 0) {
    50
                if (diff == 0) {
    51
                    return 0;
    52
                }
    53
                return diff > 0 ? type(int256).max : type(int256).min;
    54
            }
    55
            return (diff * PERCENT) / int256(denom);
    56
        }
    57
    58
        function _abs(int256 value) internal pure returns (int256) {
    59
            return value < 0 ? -value : value;
    60
        }
    61
    62
        /// @notice Invariant 1: Total borrowed assets <= total supplied assets (v0)
    63
        /// @dev Uses definition assumed by the auditors
    64
        function invariant_totalBorrowedLessThanSupplied_v0() public returns (bool) {
    65
            uint256 assetCount = iHub.getAssetCount();
    66
            int256 maxViolation = type(int256).min;
    67
    68
            for (uint256 i = 0; i < assetCount; i++) {
    69
                uint256 totalBorrowed = iHub.getAssetTotalOwed(i);
    70
                uint256 totalSupplied = iHub.getAddedShares(i);
    71
    72
                int256 diff = totalBorrowed >= totalSupplied
    73
                    ? int256(totalBorrowed - totalSupplied)
    74
                    : -int256(totalSupplied - totalBorrowed);
    75
                int256 relativeDiff = _relativeDiff(diff, totalSupplied);
    76
                if (relativeDiff > maxViolation) {
    77
                    maxViolation = relativeDiff;
    78
                }
    79
            }
    80
            if (!OPTIMIZATION_MODE) {
    81
                t(maxViolation <= 0, INVARIANT_1_TOTAL_BORROWED_LESS_THAN_SUPPLIED_V0);
    82
            }
    83
            return maxViolation <= 0;
    84
        }
    85
    86
        /// @notice Invariant 1: Total borrowed assets <= total supplied assets (v1)
    87
        /// @dev Uses definition provided by the protocol team
    88
        function invariant_totalBorrowedLessThanSupplied_v1() public returns (bool) {
    89
            uint256 assetCount = iHub.getAssetCount();
    90
            int256 maxViolation = type(int256).min;
    91
    92
            for (uint256 i = 0; i < assetCount; i++) {
    93
                uint256 totalBorrowed = iHub.getAssetTotalOwed(i);
    94
                uint256 totalSupplied = iHub.previewRemoveByShares(i, iHub.getAddedShares(i)) + iHub.getAssetAccruedFees(i);
    95
    96
                if (totalSupplied <= MIN_TOTAL_SUPPLIED) {
    97
                    continue;
    98
                }
    99
    100
                int256 diff = totalBorrowed >= totalSupplied
    101
                    ? int256(totalBorrowed - totalSupplied)
    102
                    : -int256(totalSupplied - totalBorrowed);
    103
                int256 relativeDiff = _relativeDiff(diff, totalSupplied);
    104
                if (relativeDiff > maxViolation) {
    105
                    maxViolation = relativeDiff;
    106
                }
    107
            }
    108
            if (!OPTIMIZATION_MODE) {
    109
                t(maxViolation <= 0, INVARIANT_1_TOTAL_BORROWED_LESS_THAN_SUPPLIED_V1);
    110
            }
    111
            return maxViolation <= 0;
    112
        }
    113
    114
        /// @notice Invariant 1: Total borrowed assets <= total supplied assets (v2)
    115
        /// @dev Uses definition provided by the protocol team with auditors fix
    116
        function invariant_totalBorrowedLessThanSupplied_v2() public returns (bool) {
    117
            uint256 assetCount = iHub.getAssetCount();
    118
            int256 maxViolation = type(int256).min;
    119
    120
            for (uint256 i = 0; i < assetCount; i++) {
    121
                uint256 totalBorrowed = iHub.getAssetTotalOwed(i);
    122
                uint256 totalSupplied = iHub.getAddedAssets(i) + iHub.getAssetAccruedFees(i);
    123
    124
                if (totalSupplied <= MIN_TOTAL_SUPPLIED) {
    125
                    continue;
    126
                }
    127
    128
                int256 diff = totalBorrowed >= totalSupplied
    129
                    ? int256(totalBorrowed - totalSupplied)
    130
                    : -int256(totalSupplied - totalBorrowed);
    131
                int256 relativeDiff = _relativeDiff(diff, totalSupplied);
    132
                if (relativeDiff > maxViolation) {
    133
                    maxViolation = relativeDiff;
    134
                }
    135
            }
    136
            if (!OPTIMIZATION_MODE) {
    137
                t(maxViolation <= 0, INVARIANT_1_TOTAL_BORROWED_LESS_THAN_SUPPLIED_V2);
    138
            }
    139
            return maxViolation <= 0;
    140
        }
    141
    142
        /// @notice Invariant 2: Total borrowed shares == sum of Spoke debt shares
    143
        function invariant_totalBorrowedSharesMatchesSpokeSum() public returns (bool) {
    144
            uint256 assetCount = iHub.getAssetCount();
    145
            int256 maxViolation = type(int256).min;
    146
    147
            for (uint256 i = 0; i < assetCount; i++) {
    148
                uint256 hubDrawnShares = iHub.getAssetDrawnShares(i);
    149
                uint256 spokesCount = iHub.getSpokeCount(i);
    150
    151
                uint256 sumSpokeDrawnShares = 0;
    152
                for (uint256 j = 0; j < spokesCount; j++) {
    153
                    address spoke = iHub.getSpokeAddress(i, j);
    154
                    sumSpokeDrawnShares += iHub.getSpokeDrawnShares(i, spoke);
    155
                }
    156
    157
                int256 diff = hubDrawnShares >= sumSpokeDrawnShares
    158
                    ? int256(hubDrawnShares - sumSpokeDrawnShares)
    159
                    : -int256(sumSpokeDrawnShares - hubDrawnShares);
    160
                int256 relativeDiff = _relativeDiff(_abs(diff), sumSpokeDrawnShares);
    161
                if (relativeDiff > maxViolation) {
    162
                    maxViolation = relativeDiff;
    163
                }
    164
            }
    165
            if (!OPTIMIZATION_MODE) {
    166
                t(maxViolation <= 0, INVARIANT_2_TOTAL_BORROWED_SHARES_MATCHES_SPOKE_SUM);
    167
            }
    168
            return maxViolation <= 0;
    169
        }
    170
    171
        /// @notice Invariant 3: Hub added assets >= sum of Spoke added assets (converted from shares)
    172
        function invariant_hubAddedAssetsGreaterThanSpokeSum() public returns (bool) {
    173
            uint256 assetCount = iHub.getAssetCount();
    174
            int256 maxViolation = type(int256).min;
    175
    176
            for (uint256 i = 0; i < assetCount; i++) {
    177
                uint256 addedShares = iHub.getAddedShares(i);
    178
                uint256 hubAddedAssets = iHub.previewRemoveByShares(i, addedShares);
    179
                uint256 spokesCount = iHub.getSpokeCount(i);
    180
    181
                uint256 sumSpokeAddedAssets = 0;
    182
                for (uint256 j = 0; j < spokesCount; j++) {
    183
                    address spoke = iHub.getSpokeAddress(i, j);
    184
                    sumSpokeAddedAssets += iHub.getSpokeAddedAssets(i, spoke);
    185
                }
    186
    187
                int256 diff = sumSpokeAddedAssets >= hubAddedAssets
    188
                    ? int256(sumSpokeAddedAssets - hubAddedAssets)
    189
                    : -int256(hubAddedAssets - sumSpokeAddedAssets);
    190
                int256 relativeDiff = _relativeDiff(diff, sumSpokeAddedAssets);
    191
                if (relativeDiff > maxViolation) {
    192
                    maxViolation = relativeDiff;
    193
                }
    194
            }
    195
            if (!OPTIMIZATION_MODE) {
    196
                t(maxViolation <= 0, INVARIANT_3_HUB_ADDED_ASSETS_GREATER_THAN_SPOKE_SUM);
    197
            }
    198
            return maxViolation <= 0;
    199
        }
    200
    201
        /// @notice Invariant 4: Hub added shares == sum of Spoke added shares
    202
        function invariant_hubAddedSharesMatchesSpokeSum() public returns (bool) {
    203
            uint256 assetCount = iHub.getAssetCount();
    204
            int256 maxViolation = type(int256).min;
    205
    206
            for (uint256 i = 0; i < assetCount; i++) {
    207
                uint256 hubAddedShares = iHub.getAddedShares(i);
    208
                uint256 spokesCount = iHub.getSpokeCount(i);
    209
    210
                uint256 sumSpokeAddedShares = 0;
    211
                for (uint256 j = 0; j < spokesCount; j++) {
    212
                    address spoke = iHub.getSpokeAddress(i, j);
    213
                    sumSpokeAddedShares += iHub.getSpokeAddedShares(i, spoke);
    214
                }
    215
    216
                int256 diff = hubAddedShares >= sumSpokeAddedShares
    217
                    ? int256(hubAddedShares - sumSpokeAddedShares)
    218
                    : -int256(sumSpokeAddedShares - hubAddedShares);
    219
                int256 relativeDiff = _relativeDiff(_abs(diff), sumSpokeAddedShares);
    220
                if (relativeDiff > maxViolation) {
    221
                    maxViolation = relativeDiff;
    222
                }
    223
            }
    224
            if (!OPTIMIZATION_MODE) {
    225
                t(maxViolation <= 0, INVARIANT_4_HUB_ADDED_SHARES_MATCHES_SPOKE_SUM);
    226
            }
    227
            return maxViolation <= 0;
    228
        }
    229
    230
        /// @notice Invariant 5: Supply share price and drawn index cannot decrease
    231
        function invariant_supplySharePriceAndDrawnIndexMonotonic() public returns (bool) {
    232
            uint256 assetCount = iHub.getAssetCount();
    233
            int256 maxViolation = type(int256).min;
    234
    235
            for (uint256 i = 0; i < assetCount; i++) {
    236
                uint256 currentDrawnIndex = iHub.getAssetDrawnIndex(i);
    237
                uint256 maxDrawnIndexSeen = ghost_maxDrawnIndexSeen[i];
    238
    239
                if (maxDrawnIndexSeen > 0) {
    240
                    int256 diff = currentDrawnIndex >= maxDrawnIndexSeen
    241
                        ? -int256(currentDrawnIndex - maxDrawnIndexSeen)
    242
                        : int256(maxDrawnIndexSeen - currentDrawnIndex);
    243
                    int256 relativeDiff = _relativeDiff(diff, maxDrawnIndexSeen);
    244
                    if (relativeDiff > maxViolation) {
    245
                        maxViolation = relativeDiff;
    246
                    }
    247
                }
    248
    249
                uint256 addedShares = iHub.getAddedShares(i);
    250
                if (addedShares > 0) {
    251
                    uint256 addedAssets = iHub.getAddedAssets(i);
    252
                    uint256 maxAssets = ghost_maxSupplySharePriceAssetsSeen[i];
    253
                    uint256 maxShares = ghost_maxSupplySharePriceSharesSeen[i];
    254
    255
                    if (maxShares > 0) {
    256
                        uint256 lhs = addedAssets * maxShares;
    257
                        uint256 rhs = maxAssets * addedShares;
    258
                        int256 diff = lhs >= rhs ? -int256(lhs - rhs) : int256(rhs - lhs);
    259
                        int256 relativeDiff = _relativeDiff(diff, rhs);
    260
                        if (relativeDiff > maxViolation) {
    261
                            maxViolation = relativeDiff;
    262
                        }
    263
                    }
    264
                }
    265
    266
                _updateMonotonicGhosts(i);
    267
            }
    268
            if (!OPTIMIZATION_MODE) {
    269
                t(maxViolation <= 0, INVARIANT_5_SUPPLY_SHARE_PRICE_AND_DRAWN_INDEX_MONOTONIC);
    270
            }
    271
            return maxViolation <= 0;
    272
        }
    273
    274
        /// @dev Reference https://www.certora.com/blog/the-holy-grail
    275
        function invariant_shouldNotBecomeLiquidatable() public returns (bool) {
    276
            int256 maxViolation = type(int256).min;
    277
            if (_after.operation != Operation.SetPrice) {
    278
                int256 diff = (_before.isAnyUserLiquidatable || !_after.isAnyUserLiquidatable) ? int256(0) : PERCENT;
    279
                if (diff > maxViolation) {
    280
                    maxViolation = diff;
    281
                }
    282
            }
    283
            if (!OPTIMIZATION_MODE) {
    284
                t(maxViolation <= 0, INVARIANT_HOLY_GRAIL_SHOULD_NOT_BECOME_LIQUIDATABLE);
    285
            }
    286
            return maxViolation <= 0;
    287
        }
    288
    289
        /// @dev Canary assertion helper. A failing input is expected to be discovered during fuzzing.
    290
        function assert_canary_ASSERTION_CANARY(uint256 entropy) public {
    291
            t(entropy > 0, ASSERTION_CANARY);
    292
        }
    293
    294
        /// @dev Canary global invariant expected to fail immediately.
    295
        function invariant_canary() public returns (bool) {
    296
            int256 maxViolation = PERCENT;
    297
            if (!OPTIMIZATION_MODE) {
    298
                t(maxViolation <= 0, INVARIANT_CANARY_GLOBAL_INVARIANT_FAILURE);
    299
            }
    300
            return maxViolation <= 0;
    301
        }
    302
    }
    303
    100.0% tests/recon/Setup.sol
    Lines covered: 29 / 29 (100.0%)
    1
    // SPDX-License-Identifier: GPL-2.0
    2
    pragma solidity ^0.8.0;
    3
    4
    // Chimera deps
    5
    import {BaseSetup} from "@chimera/BaseSetup.sol";
    6
    import {vm} from "@chimera/Hevm.sol";
    7
    8
    // Managers
    9
    import {ActorManager} from "@recon/ActorManager.sol";
    10
    import {AssetManager} from "@recon/AssetManager.sol";
    11
    12
    // Helpers
    13
    import {Utils as ReconUtils} from "@recon/Utils.sol";
    14
    15
    // Your deps
    16
    import "src/spoke/interfaces/IAaveOracle.sol";
    17
    import "src/hub/interfaces/IHub.sol";
    18
    import "src/spoke/interfaces/ISpoke.sol";
    19
    20
    import "tests/Base.t.sol";
    21
    22
    abstract contract Setup is BaseSetup, ActorManager, AssetManager, ReconUtils, Base {
    23
        mapping(address underlying => uint256 maxAmount) internal _maxByUnderlying;
    24
    25
        IAaveOracle iAaveOracle;
    26
        IHub iHub;
    27
        ISpoke iSpoke;
    28
        
    29
        /// === Setup === ///
    30
        /// This contains all calls to be performed in the tester constructor, both for Echidna and Foundry
    31
        function setup() internal virtual override {
    32
            deployFixtures();
    33
            initEnvironment();
    34
    35
            iAaveOracle = oracle1;
    36
            iHub = hub1;
    37
            iSpoke = spoke1;
    38
    39
            _addAsset(address(tokenList.weth));
    40
            _maxByUnderlying[address(tokenList.weth)] = 10e3 * 10 ** tokenList.weth.decimals();
    41
            _addAsset(address(tokenList.usdx));
    42
            _maxByUnderlying[address(tokenList.usdx)] = 100e3 * 10 ** tokenList.usdx.decimals();
    43
            _addAsset(address(tokenList.dai));
    44
            _maxByUnderlying[address(tokenList.dai)] = 100e3 * 10 ** tokenList.dai.decimals();
    45
            _addAsset(address(tokenList.wbtc));
    46
            _maxByUnderlying[address(tokenList.wbtc)] = 10e3 * 10 ** tokenList.wbtc.decimals();
    47
            _addAsset(address(tokenList.usdy));
    48
            _maxByUnderlying[address(tokenList.usdy)] = 100e3 * 10 ** tokenList.usdy.decimals();
    49
            _addAsset(address(tokenList.usdz));
    50
            _maxByUnderlying[address(tokenList.usdz)] = 100e3 * 10 ** tokenList.usdz.decimals();
    51
    52
            _switchAsset(0);
    53
    54
            _addActor(alice);
    55
            _addActor(bob);
    56
            _addActor(LIQUIDATOR);
    57
    58
            _switchActor(0);
    59
        }
    60
    61
        /// === HELPERS === ///
    62
        /// Get the max amount for a given reserve based on its underlying token decimals (avoids Low likelihood scenarios in Audit Contest)
    63
        function _max(uint256 reserveId) internal view returns (uint256) {
    64
            ISpoke.Reserve memory reserve = iSpoke.getReserve(reserveId);
    65
            address underlying = reserve.underlying;
    66
            uint256 maxAmount = _maxByUnderlying[underlying];
    67
            require(maxAmount > 0, "Max not set for underlying");
    68
            return maxAmount;
    69
        }
    70
    }
    71
    0.0% tests/recon/TargetFunctions.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: GPL-2.0
    2
    pragma solidity ^0.8.0;
    3
    4
    // Chimera deps
    5
    import {vm} from "@chimera/Hevm.sol";
    6
    7
    // Helpers
    8
    import {Panic} from "@recon/Panic.sol";
    9
    10
    // Targets
    11
    // NOTE: Always import and apply them in alphabetical order, so much easier to debug!
    12
    import { AdminTargets } from "./targets/AdminTargets.sol";
    13
    import { DoomsdayTargets } from "./targets/DoomsdayTargets.sol";
    14
    import { IAaveOracleTargets } from "./targets/IAaveOracleTargets.sol";
    15
    import { IHubTargets } from "./targets/IHubTargets.sol";
    16
    import { ISpokeTargets } from "./targets/ISpokeTargets.sol";
    17
    import { ManagersTargets } from "./targets/ManagersTargets.sol";
    18
    19
    abstract contract TargetFunctions is
    20
        AdminTargets,
    21
        DoomsdayTargets,
    22
        IAaveOracleTargets,
    23
        IHubTargets,
    24
        ISpokeTargets,
    25
        ManagersTargets
    26
    {
    27
        /// CUSTOM TARGET FUNCTIONS - Add your own target functions here ///
    28
    29
    30
        /// AUTO GENERATED TARGET FUNCTIONS - WARNING: DO NOT DELETE OR MODIFY THIS LINE ///
    31
    }
    32
    0.0% tests/recon/targets/AdminTargets.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: GPL-2.0
    2
    pragma solidity ^0.8.0;
    3
    4
    import {BaseTargetFunctions} from "@chimera/BaseTargetFunctions.sol";
    5
    import {BeforeAfter} from "../BeforeAfter.sol";
    6
    import {Properties} from "../Properties.sol";
    7
    // Chimera deps
    8
    import {vm} from "@chimera/Hevm.sol";
    9
    10
    // Helpers
    11
    import {Panic} from "@recon/Panic.sol";
    12
    13
    abstract contract AdminTargets is
    14
        BaseTargetFunctions,
    15
        Properties
    16
    {
    17
        /// CUSTOM TARGET FUNCTIONS - Add your own target functions here ///
    18
    19
    20
        /// AUTO GENERATED TARGET FUNCTIONS - WARNING: DO NOT DELETE OR MODIFY THIS LINE ///
    21
    }
    0.0% tests/recon/targets/DoomsdayTargets.sol
    Lines covered: 0 / 0 (0.0%)
    1
    // SPDX-License-Identifier: GPL-2.0
    2
    pragma solidity ^0.8.0;
    3
    4
    import {BaseTargetFunctions} from "@chimera/BaseTargetFunctions.sol";
    5
    import {BeforeAfter} from "../BeforeAfter.sol";
    6
    import {Properties} from "../Properties.sol";
    7
    // Chimera deps
    8
    import {vm} from "@chimera/Hevm.sol";
    9
    10
    // Helpers
    11
    import {Panic} from "@recon/Panic.sol";
    12
    13
    abstract contract DoomsdayTargets is
    14
        BaseTargetFunctions,
    15
        Properties
    16
    {
    17
        /// Makes a handler have no side effects
    18
        /// The fuzzer will call this anyway, and because it reverts it will be removed from shrinking
    19
        /// Replace the "withGhosts" with "stateless" to make the code clean
    20
        modifier stateless() {
    21
            _;
    22
            revert("stateless");
    23
        }
    24
    }
    100.0% tests/recon/targets/IAaveOracleTargets.sol
    Lines covered: 17 / 17 (100.0%)
    1
    // SPDX-License-Identifier: GPL-2.0
    2
    pragma solidity ^0.8.0;
    3
    4
    import {BaseTargetFunctions} from "@chimera/BaseTargetFunctions.sol";
    5
    import {BeforeAfter} from "../BeforeAfter.sol";
    6
    import {Properties} from "../Properties.sol";
    7
    // Chimera deps
    8
    import {vm} from "@chimera/Hevm.sol";
    9
    10
    // Helpers
    11
    import {Panic} from "@recon/Panic.sol";
    12
    13
    import "src/spoke/interfaces/IAaveOracle.sol";
    14
    import "src/dependencies/chainlink/AggregatorV3Interface.sol";
    15
    import "src/spoke/AaveOracle.sol";
    16
    import "tests/mocks/MockPriceFeed.sol";
    17
    18
    abstract contract IAaveOracleTargets is
    19
        BaseTargetFunctions,
    20
        Properties
    21
    {
    22
        /// Price can change by up to 100x or 1/100x (avoids Low likelihood scenarios in Audit Contest)
    23
        uint256 private constant MAX_PRICE_CHANGE_FACTOR = 100;
    24
        mapping(uint256 reserveId => uint256 originalPrice) private _originalPrices;
    25
        /// CUSTOM TARGET FUNCTIONS - Add your own target functions here ///
    26
    27
    28
        /// AUTO GENERATED TARGET FUNCTIONS - WARNING: DO NOT DELETE OR MODIFY THIS LINE ///
    29
    30
        function iAaveOracle_setReserveSource(uint256 reserveId, address source) private asActor {
    31
            iAaveOracle.setReserveSource(reserveId, source);
    32
        }
    33
    34
        function iAaveOracle_setPrice(uint256 reserveId, uint256 price) public asAdmin {
    35
            uint256 reserveCount = iSpoke.getReserveCount();
    36
            require(reserveCount > 0);
    37
    38
            reserveId = between(reserveId, 0, reserveCount - 1);
    39
    40
            uint256 basePrice = _getOriginalPrice(reserveId);
    41
    42
            price = between(price, basePrice / MAX_PRICE_CHANGE_FACTOR, basePrice * MAX_PRICE_CHANGE_FACTOR);
    43
            AaveOracle oracle = AaveOracle(iSpoke.ORACLE());
    44
            address mockPriceFeed = address(
    45
                new MockPriceFeed(oracle.DECIMALS(), oracle.DESCRIPTION(), price)
    46
            );
    47
            iSpoke.updateReservePriceSource(reserveId, mockPriceFeed);
    48
            _after.operation = Operation.SetPrice;
    49
        }
    50
    51
        function _getOriginalPrice(uint256 reserveId) private returns (uint256 originalPrice) {
    52
            originalPrice = _originalPrices[reserveId];
    53
            if (originalPrice == 0) {
    54
                (, int256 answer,,,) = AggregatorV3Interface(iAaveOracle.getReserveSource(reserveId)).latestRoundData();
    55
                originalPrice = uint256(answer);
    56
                _originalPrices[reserveId] = originalPrice;
    57
            }
    58
        }
    59
    }
    60
    100.0% tests/recon/targets/IHubTargets.sol
    Lines covered: 32 / 32 (100.0%)
    1
    // SPDX-License-Identifier: GPL-2.0
    2
    pragma solidity ^0.8.0;
    3
    4
    import {BaseTargetFunctions} from "@chimera/BaseTargetFunctions.sol";
    5
    import {BeforeAfter} from "../BeforeAfter.sol";
    6
    import {Properties} from "../Properties.sol";
    7
    // Chimera deps
    8
    import {vm} from "@chimera/Hevm.sol";
    9
    10
    // Helpers
    11
    import {Panic} from "@recon/Panic.sol";
    12
    13
    import "src/hub/interfaces/IHub.sol";
    14
    import "src/hub/interfaces/IAssetInterestRateStrategy.sol";
    15
    16
    abstract contract IHubTargets is BaseTargetFunctions, Properties {
    17
        /// CUSTOM TARGET FUNCTIONS - Add your own target functions here ///
    18
    19
        /// AUTO GENERATED TARGET FUNCTIONS - WARNING: DO NOT DELETE OR MODIFY THIS LINE ///
    20
    21
        function iHub_add(uint256 assetId, uint256 amount) private asActor {
    22
            iHub.add(assetId, amount);
    23
        }
    24
    25
        function iHub_addAsset(
    26
            address underlying,
    27
            uint8 decimals,
    28
            address feeReceiver,
    29
            address irStrategy,
    30
            bytes memory irData
    31
        ) private asActor {
    32
            iHub.addAsset(underlying, decimals, feeReceiver, irStrategy, irData);
    33
        }
    34
    35
        function iHub_addSpoke(uint256 assetId, address spoke, IHub.SpokeConfig memory params) private asActor {
    36
            iHub.addSpoke(assetId, spoke, params);
    37
        }
    38
    39
        function iHub_draw(uint256 assetId, uint256 amount, address to) private asActor {
    40
            iHub.draw(assetId, amount, to);
    41
        }
    42
    43
        function iHub_eliminateDeficit(uint256 assetId, uint256 amount, address spoke) private asActor {
    44
            iHub.eliminateDeficit(assetId, amount, spoke);
    45
        }
    46
    47
        function iHub_mintFeeShares_ASSERTION_MINT_FEE_SHARES_PPS_CHANGE(uint256 assetId) public asAdmin {
    48
            uint256 assetCount = iHub.getAssetCount();
    49
            require(assetCount > 0);
    50
    51
            assetId = between(assetId, 0, assetCount - 1);
    52
            uint256 oldPPS = _pps(assetId);
    53
            iHub.mintFeeShares(assetId);
    54
            uint256 newPPS = _pps(assetId);
    55
    56
            uint256 diff = oldPPS > newPPS ? oldPPS - newPPS : newPPS - oldPPS;
    57
            uint256 relativeDiff = (diff * 1e18) / oldPPS;
    58
    59
            lte(relativeDiff, 1, ASSERTION_MINT_FEE_SHARES_PPS_CHANGE);
    60
        }
    61
    62
        function _pps(uint256 assetId) private view returns (uint256) {
    63
            return iHub.getAddedAssets(assetId) * 1e18 / iHub.getAddedShares(assetId);
    64
        }
    65
    66
        function iHub_payFeeShares(uint256 assetId, uint256 shares) private asActor {
    67
            iHub.payFeeShares(assetId, shares);
    68
        }
    69
    70
        function iHub_reclaim(uint256 assetId, uint256 amount) private asActor {
    71
            iHub.reclaim(assetId, amount);
    72
        }
    73
    74
        function iHub_refreshPremium(uint256 assetId, IHubBase.PremiumDelta memory premiumDelta) private asActor {
    75
            iHub.refreshPremium(assetId, premiumDelta);
    76
        }
    77
    78
        function iHub_remove(uint256 assetId, uint256 amount, address to) private asActor {
    79
            iHub.remove(assetId, amount, to);
    80
        }
    81
    82
        function iHub_reportDeficit(uint256 assetId, uint256 drawnAmount, IHubBase.PremiumDelta memory premiumDelta)
    83
            private
    84
            asActor
    85
        {
    86
            iHub.reportDeficit(assetId, drawnAmount, premiumDelta);
    87
        }
    88
    89
        function iHub_restore(uint256 assetId, uint256 drawnAmount, IHubBase.PremiumDelta memory premiumDelta)
    90
            private
    91
            asActor
    92
        {
    93
            iHub.restore(assetId, drawnAmount, premiumDelta);
    94
        }
    95
    96
        function iHub_setAuthority(address) private asActor {
    97
            iHub.setAuthority(address(0));
    98
        }
    99
    100
        function iHub_setInterestRateData(uint256 assetId, bytes memory irData) private asActor {
    101
            iHub.setInterestRateData(assetId, irData);
    102
        }
    103
    104
        function iHub_setInterestRateData(uint256 assetId, IAssetInterestRateStrategy.InterestRateData memory irData)
    105
            public
    106
            asAdmin
    107
        {
    108
            uint256 assetCount = iHub.getAssetCount();
    109
            require(assetCount > 0);
    110
    111
            assetId = between(assetId, 0, assetCount - 1);
    112
            iHub.setInterestRateData(assetId, abi.encode(irData));
    113
        }
    114
    115
        function iHub_sweep(uint256 assetId, uint256 amount) private asActor {
    116
            iHub.sweep(assetId, amount);
    117
        }
    118
    119
        function iHub_transferShares(uint256 assetId, uint256 shares, address toSpoke) private asActor {
    120
            iHub.transferShares(assetId, shares, toSpoke);
    121
        }
    122
    123
        function iHub_updateAssetConfig(uint256 assetId, IHub.AssetConfig memory config, bytes memory irData)
    124
            private
    125
            asActor
    126
        {
    127
            iHub.updateAssetConfig(assetId, config, irData);
    128
        }
    129
    130
        function iHub_updateAssetConfig(
    131
            uint256 assetId,
    132
            IHub.AssetConfig memory config,
    133
            IAssetInterestRateStrategy.InterestRateData memory irData
    134
        ) public asAdmin {
    135
            uint256 assetCount = iHub.getAssetCount();
    136
            require(assetCount > 0);
    137
    138
            assetId = between(assetId, 0, assetCount - 1);
    139
    140
            iHub.updateAssetConfig(assetId, config, abi.encode(irData));
    141
        }
    142
    143
        function iHub_updateSpokeConfig(uint256 assetId, address spoke, IHub.SpokeConfig memory config) private asActor {
    144
            iHub.updateSpokeConfig(assetId, spoke, config);
    145
        }
    146
    147
        function iHub_updateSpokeConfig(uint256 assetId, uint256 spokeId, IHub.SpokeConfig memory config) public asAdmin {
    148
            uint256 assetCount = iHub.getAssetCount();
    149
            require(assetCount > 0);
    150
    151
            assetId = between(assetId, 0, assetCount - 1);
    152
    153
            uint256 spokeCount = iHub.getSpokeCount(assetId);
    154
            require(spokeCount > 0);
    155
    156
            spokeId = between(spokeId, 0, spokeCount - 1);
    157
    158
            address spoke = iHub.getSpokeAddress(assetId, spokeId);
    159
            iHub.updateSpokeConfig(assetId, spoke, config);
    160
        }
    161
    }
    162
    100.0% tests/recon/targets/ISpokeTargets.sol
    Lines covered: 117 / 117 (100.0%)
    1
    // SPDX-License-Identifier: GPL-2.0
    2
    pragma solidity ^0.8.0;
    3
    4
    import {BaseTargetFunctions} from "@chimera/BaseTargetFunctions.sol";
    5
    import {BeforeAfter} from "../BeforeAfter.sol";
    6
    import {Properties} from "../Properties.sol";
    7
    // Chimera deps
    8
    import {vm} from "@chimera/Hevm.sol";
    9
    10
    // Helpers
    11
    import {Panic} from "@recon/Panic.sol";
    12
    13
    import "src/hub/interfaces/IHub.sol";
    14
    import "src/spoke/interfaces/ISpoke.sol";
    15
    import "src/spoke/interfaces/IAaveOracle.sol";
    16
    import "src/dependencies/openzeppelin/Ownable.sol";
    17
    import "src/dependencies/openzeppelin/IERC20Errors.sol";
    18
    import "src/dependencies/weth/WETH9.sol";
    19
    import "src/spoke/libraries/LiquidationLogic.sol";
    20
    21
    abstract contract ISpokeTargets is BaseTargetFunctions, Properties {
    22
        /// CUSTOM TARGET FUNCTIONS - Add your own target functions here ///
    23
    24
        /// AUTO GENERATED TARGET FUNCTIONS - WARNING: DO NOT DELETE OR MODIFY THIS LINE ///
    25
    26
        function iSpoke_addDynamicReserveConfig(uint256 reserveId, ISpoke.DynamicReserveConfig memory dynamicConfig)
    27
            public
    28
            asAdmin
    29
        {
    30
            uint256 reserveCount = iSpoke.getReserveCount();
    31
            require(reserveCount > 0);
    32
    33
            reserveId = between(reserveId, 0, reserveCount - 1);
    34
            iSpoke.addDynamicReserveConfig(reserveId, dynamicConfig);
    35
        }
    36
    37
        function iSpoke_addReserve(
    38
            address hub,
    39
            uint256 assetId,
    40
            address priceSource,
    41
            ISpoke.ReserveConfig memory config,
    42
            ISpoke.DynamicReserveConfig memory dynamicConfig
    43
        ) private asActor {
    44
            iSpoke.addReserve(hub, assetId, priceSource, config, dynamicConfig);
    45
        }
    46
    47
        function iSpoke_borrow(uint256 reserveId, uint256 amount, address onBehalfOf) private asActor {
    48
            iSpoke.borrow(reserveId, amount, onBehalfOf);
    49
        }
    50
    51
        function iSpoke_borrow(uint256 reserveId, uint256 amount) public asActor {
    52
            uint256 reserveCount = iSpoke.getReserveCount();
    53
            require(reserveCount > 0);
    54
    55
            reserveId = between(reserveId, 0, reserveCount - 1);
    56
            amount = between(amount, 0, _max(reserveId));
    57
    58
            iSpoke.borrow(reserveId, amount, _getActor());
    59
        }
    60
    61
        function iSpoke_liquidationCall(
    62
            uint256 collateralReserveId,
    63
            uint256 debtReserveId,
    64
            address user,
    65
            uint256 debtToCover,
    66
            bool receiveShares
    67
        ) private asActor {
    68
            iSpoke.liquidationCall(collateralReserveId, debtReserveId, user, debtToCover, receiveShares);
    69
        }
    70
    71
        function iSpoke_liquidationCall_ASSERTION_LIQUIDATION_CALL_DOS(uint256 collateralReserveId, uint256 debtReserveId, uint256 userId, uint256 debtToCover, bool receiveShares) public asActor {
    72
            uint256 reserveCount = iSpoke.getReserveCount();
    73
            require(reserveCount > 1);
    74
            address[] memory actors = _getActors();
    75
            require(actors.length > 0);
    76
    77
            collateralReserveId = between(collateralReserveId, 0, reserveCount - 1);
    78
            debtReserveId = between(debtReserveId, 0, reserveCount - 1);
    79
            debtToCover = between(debtToCover, 0, _max(debtReserveId));
    80
            userId = between(userId, 0, actors.length - 1);
    81
            address user = actors[userId];
    82
    83
            try iSpoke.liquidationCall(collateralReserveId, debtReserveId, user, debtToCover, receiveShares) {}
    84
            catch (bytes memory err) {
    85
                t(
    86
                    bytes4(err) == ISpoke.ReserveNotListed.selector || bytes4(err) == ISpoke.SelfLiquidation.selector
    87
                        || bytes4(err) == ISpoke.InvalidDebtToCover.selector
    88
                        || bytes4(err) == IERC20Errors.ERC20InsufficientAllowance.selector
    89
                        || bytes4(err) == IERC20Errors.ERC20InsufficientBalance.selector
    90
                        || bytes4(err) == WETH9.InsufficientAllowance.selector
    91
                        || bytes4(err) == WETH9.InsufficientBalance.selector || bytes4(err) == ISpoke.ReservePaused.selector
    92
                        || bytes4(err) == ISpoke.ReserveNotSupplied.selector
    93
                        || bytes4(err) == ISpoke.ReserveNotBorrowed.selector
    94
                        || bytes4(err) == ISpoke.CollateralCannotBeLiquidated.selector
    95
                        || bytes4(err) == ISpoke.HealthFactorNotBelowThreshold.selector
    96
                        || bytes4(err) == ISpoke.ReserveNotEnabledAsCollateral.selector
    97
                        || bytes4(err) == ISpoke.CannotReceiveShares.selector || bytes4(err) == ISpoke.MustNotLeaveDust.selector
    98
                        || bytes4(err) == IHub.InvalidAmount.selector || bytes4(err) == IHub.SpokeNotActive.selector
    99
                        || bytes4(err) == IHub.SpokePaused.selector
    100
                        || (bytes4(err) == IHub.InsufficientLiquidity.selector && !receiveShares)
    101
                        || bytes4(err) == IAaveOracle.InvalidPrice.selector,
    102
                    ASSERTION_LIQUIDATION_CALL_DOS
    103
                );
    104
                require(false);
    105
            }
    106
        }
    107
    108
        function iSpoke_multicall(bytes[] memory data) private asActor {
    109
            iSpoke.multicall(data);
    110
        }
    111
    112
        function iSpoke_permitReserve(
    113
            uint256 reserveId,
    114
            address onBehalfOf,
    115
            uint256 value,
    116
            uint256 deadline,
    117
            uint8 permitV,
    118
            bytes32 permitR,
    119
            bytes32 permitS
    120
        ) private asActor {
    121
            iSpoke.permitReserve(reserveId, onBehalfOf, value, deadline, permitV, permitR, permitS);
    122
        }
    123
    124
        function iSpoke_renouncePositionManagerRole(address user) private asActor {
    125
            iSpoke.renouncePositionManagerRole(user);
    126
        }
    127
    128
        function iSpoke_repay(uint256 reserveId, uint256 amount, address onBehalfOf) private asActor {
    129
            iSpoke.repay(reserveId, amount, onBehalfOf);
    130
        }
    131
    132
        function iSpoke_repay_ASSERTION_REPAY_DOS(uint256 reserveId, uint256 amount) public asActor {
    133
            uint256 reserveCount = iSpoke.getReserveCount();
    134
            require(reserveCount > 1);
    135
    136
            reserveId = between(reserveId, 0, reserveCount - 1);
    137
            amount = between(amount, 0, _max(reserveId));
    138
    139
            uint256 value0;
    140
            uint256 value1;
    141
            try iSpoke.repay(reserveId, amount, _getActor()) returns (uint256 tempValue0, uint256 tempValue1) {
    142
                value0 = tempValue0;
    143
                value1 = tempValue1;
    144
            } catch (bytes memory err) {
    145
                t(
    146
                    bytes4(err) == ISpoke.Unauthorized.selector || bytes4(err) == ISpoke.ReserveNotListed.selector
    147
                        || bytes4(err) == ISpoke.ReservePaused.selector
    148
                        || bytes4(err) == IERC20Errors.ERC20InsufficientAllowance.selector
    149
                        || bytes4(err) == IERC20Errors.ERC20InsufficientBalance.selector
    150
                        || bytes4(err) == WETH9.InsufficientAllowance.selector
    151
                        || bytes4(err) == WETH9.InsufficientBalance.selector || bytes4(err) == IHub.InvalidAmount.selector
    152
                        || bytes4(err) == IHub.SpokeNotActive.selector || bytes4(err) == IHub.SpokePaused.selector
    153
                        || bytes4(err) == IHub.SurplusDrawnRestored.selector
    154
                        || bytes4(err) == IHub.SurplusPremiumRayRestored.selector
    155
                        || bytes4(err) == IAaveOracle.InvalidPrice.selector,
    156
                    ASSERTION_REPAY_DOS
    157
                );
    158
                require(false);
    159
            }
    160
        }
    161
    162
        function iSpoke_setAuthority(address) private asActor {
    163
            iSpoke.setAuthority(address(0));
    164
        }
    165
    166
        function iSpoke_setUserPositionManager(address positionManager, bool approve) private asActor {
    167
            iSpoke.setUserPositionManager(positionManager, approve);
    168
        }
    169
    170
        function iSpoke_setUserPositionManagerWithSig(
    171
            address positionManager,
    172
            address user,
    173
            bool approve,
    174
            uint256 nonce,
    175
            uint256 deadline,
    176
            bytes memory signature
    177
        ) private asActor {
    178
            iSpoke.setUserPositionManagerWithSig(positionManager, user, approve, nonce, deadline, signature);
    179
        }
    180
    181
        function iSpoke_setUsingAsCollateral(uint256 reserveId, bool usingAsCollateral, address onBehalfOf)
    182
            private
    183
            asActor
    184
        {
    185
            iSpoke.setUsingAsCollateral(reserveId, usingAsCollateral, onBehalfOf);
    186
        }
    187
    188
        function iSpoke_setUsingAsCollateral(uint256 reserveId, bool usingAsCollateral) public asActor {
    189
            uint256 reserveCount = iSpoke.getReserveCount();
    190
            require(reserveCount > 1);
    191
    192
            reserveId = between(reserveId, 0, reserveCount - 1);
    193
            iSpoke.setUsingAsCollateral(reserveId, usingAsCollateral, _getActor());
    194
        }
    195
    196
        function iSpoke_supply(uint256 reserveId, uint256 amount, address onBehalfOf) private asActor {
    197
            iSpoke.supply(reserveId, amount, onBehalfOf);
    198
        }
    199
    200
        function iSpoke_supply_ASSERTION_SUPPLY_DOS(uint256 reserveId, uint256 amount) public asActor {
    201
            uint256 reserveCount = iSpoke.getReserveCount();
    202
            require(reserveCount > 1);
    203
    204
            reserveId = between(reserveId, 0, reserveCount - 1);
    205
            amount = between(amount, 0, _max(reserveId));
    206
    207
            uint256 value0;
    208
            uint256 value1;
    209
            try iSpoke.supply(reserveId, amount, _getActor()) returns (uint256 tempValue0, uint256 tempValue1) {
    210
                value0 = tempValue0;
    211
                value1 = tempValue1;
    212
            } catch (bytes memory err) {
    213
                t(
    214
                    bytes4(err) == ISpoke.ReserveNotListed.selector || bytes4(err) == ISpoke.ReservePaused.selector
    215
                        || bytes4(err) == IERC20Errors.ERC20InsufficientAllowance.selector
    216
                        || bytes4(err) == IERC20Errors.ERC20InsufficientBalance.selector
    217
                        || bytes4(err) == WETH9.InsufficientAllowance.selector
    218
                        || bytes4(err) == WETH9.InsufficientBalance.selector || bytes4(err) == ISpoke.ReserveFrozen.selector
    219
                        || bytes4(err) == IHub.InvalidShares.selector || bytes4(err) == IHub.InvalidAmount.selector
    220
                        || bytes4(err) == IHub.SpokeNotActive.selector || bytes4(err) == IHub.AddCapExceeded.selector
    221
                        || bytes4(err) == IHub.SpokePaused.selector,
    222
                    ASSERTION_SUPPLY_DOS
    223
                );
    224
                require(false);
    225
            }
    226
        }
    227
    228
        function iSpoke_updateDynamicReserveConfig(
    229
            uint256 reserveId,
    230
            uint24 dynamicConfigKey,
    231
            ISpoke.DynamicReserveConfig memory dynamicConfig
    232
        ) public asAdmin {
    233
            uint256 reserveCount = iSpoke.getReserveCount();
    234
            require(reserveCount > 0);
    235
    236
            reserveId = between(reserveId, 0, reserveCount - 1);
    237
    238
            dynamicConfigKey = uint24(between(dynamicConfigKey, 0, uint256(iSpoke.getReserve(reserveId).dynamicConfigKey)));
    239
            iSpoke.updateDynamicReserveConfig(reserveId, dynamicConfigKey, dynamicConfig);
    240
        }
    241
    242
        function iSpoke_updateLiquidationConfig(ISpoke.LiquidationConfig memory config) public asAdmin {
    243
            iSpoke.updateLiquidationConfig(config);
    244
        }
    245
    246
        function iSpoke_updatePositionManager(address positionManager, bool active) private asActor {
    247
            iSpoke.updatePositionManager(positionManager, active);
    248
        }
    249
    250
        function iSpoke_updateReserveConfig(uint256 reserveId, ISpoke.ReserveConfig memory params) public asAdmin {
    251
            uint256 reserveCount = iSpoke.getReserveCount();
    252
            require(reserveCount > 0);
    253
    254
            reserveId = between(reserveId, 0, reserveCount - 1);
    255
            iSpoke.updateReserveConfig(reserveId, params);
    256
        }
    257
    258
        function iSpoke_updateReservePriceSource(uint256 reserveId, address priceSource) private asActor {
    259
            iSpoke.updateReservePriceSource(reserveId, priceSource);
    260
        }
    261
    262
        function iSpoke_updateUserDynamicConfig(address onBehalfOf) private asActor {
    263
            iSpoke.updateUserDynamicConfig(onBehalfOf);
    264
        }
    265
    266
        function iSpoke_updateUserDynamicConfig() public asActor {
    267
            iSpoke.updateUserDynamicConfig(_getActor());
    268
        }
    269
    270
        function iSpoke_updateUserRiskPremium(address onBehalfOf) private asActor {
    271
            iSpoke.updateUserRiskPremium(onBehalfOf);
    272
        }
    273
    274
        function iSpoke_updateUserRiskPremium() public asActor {
    275
            iSpoke.updateUserRiskPremium(_getActor());
    276
        }
    277
    278
        function iSpoke_useNonce(uint192 key) private asActor {
    279
            iSpoke.useNonce(key);
    280
        }
    281
    282
        function iSpoke_withdraw(uint256 reserveId, uint256 amount, address onBehalfOf) private asActor {
    283
            iSpoke.withdraw(reserveId, amount, onBehalfOf);
    284
        }
    285
    286
        function iSpoke_withdraw_ASSERTION_WITHDRAW_DOS(uint256 reserveId, uint256 amount) public asActor {
    287
            uint256 reserveCount = iSpoke.getReserveCount();
    288
            require(reserveCount > 1);
    289
    290
            reserveId = between(reserveId, 0, reserveCount - 1);
    291
            amount = between(amount, 0, _max(reserveId));
    292
    293
            uint256 value0;
    294
            uint256 value1;
    295
            try iSpoke.withdraw(reserveId, amount, _getActor()) returns (uint256 tempValue0, uint256 tempValue1) {
    296
                value0 = tempValue0;
    297
                value1 = tempValue1;
    298
            } catch (bytes memory err) {
    299
                t(
    300
                    bytes4(err) == ISpoke.Unauthorized.selector || bytes4(err) == ISpoke.ReserveNotListed.selector
    301
                        || bytes4(err) == ISpoke.ReservePaused.selector || bytes4(err) == IHub.InvalidAddress.selector
    302
                        || bytes4(err) == IHub.InvalidAmount.selector || bytes4(err) == IHub.SpokeNotActive.selector
    303
                        || bytes4(err) == IHub.SpokePaused.selector || bytes4(err) == IHub.InsufficientLiquidity.selector
    304
                        || bytes4(err) == ISpoke.HealthFactorBelowThreshold.selector
    305
                        || bytes4(err) == Ownable.OwnableUnauthorizedAccount.selector,
    306
                    ASSERTION_WITHDRAW_DOS
    307
                );
    308
                require(false);
    309
            }
    310
        }
    311
    }
    312
    100.0% tests/recon/targets/ManagersTargets.sol
    Lines covered: 16 / 16 (100.0%)
    1
    // SPDX-License-Identifier: GPL-2.0
    2
    pragma solidity ^0.8.0;
    3
    4
    import {BaseTargetFunctions} from "@chimera/BaseTargetFunctions.sol";
    5
    import {BeforeAfter} from "../BeforeAfter.sol";
    6
    import {Properties} from "../Properties.sol";
    7
    import {vm} from "@chimera/Hevm.sol";
    8
    9
    import {MockERC20} from "@recon/MockERC20.sol";
    10
    11
    12
    // Target functions that are effectively inherited from the Actor and AssetManagers
    13
    // Once properly standardized, managers will expose these by default
    14
    // Keeping them out makes your project more custom
    15
    abstract contract ManagersTargets is
    16
        BaseTargetFunctions,
    17
        Properties
    18
    {
    19
        // == ACTOR HANDLERS == //
    20
        
    21
        /// @dev Start acting as another actor
    22
        /// @dev Skip address(this) as it is not seeded by Setup
    23
        /// @dev Separate ADMIN from regular users to discard 'admin is trusted' scenarios
    24
        function switchActor(uint256 entropy) public {
    25
            uint256 actorCount = _getActors().length;
    26
            require(actorCount > 1);
    27
            entropy = between(entropy, 1, actorCount - 1);
    28
            _switchActor(entropy);
    29
        }
    30
    31
    32
        /// @dev Starts using a new asset
    33
        function switch_asset(uint256 entropy) public {
    34
            uint256 assetCount = _getAssets().length;
    35
            require(assetCount > 0);
    36
            entropy = between(entropy, 0, assetCount - 1);
    37
            _switchAsset(entropy);
    38
        }
    39
    40
        function switch_spoke(uint256 entropy) public {
    41
            uint256 index = between(entropy, 0, 2);
    42
            iSpoke = index == 0 ? spoke1 : index == 1 ? spoke2 : spoke3;
    43
        }
    44
    45
        function switch_oracle(uint256 entropy) public {
    46
            uint256 index = between(entropy, 0, 2);
    47
            iAaveOracle = index == 0 ? oracle1 : index == 1 ? oracle2 : oracle3;
    48
        }
    49
    50
        /// @dev Deploy a new token and add it to the list of assets, then set it as the current asset
    51
        function add_new_asset(uint8 decimals) private returns (address) {
    52
            address newAsset = _newAsset(decimals);
    53
            return newAsset;
    54
        }
    55
    56
        /// === GHOST UPDATING HANDLERS ===///
    57
        /// We `updateGhosts` cause you never know (e.g. donations)
    58
        /// If you don't want to track donations, remove the `updateGhosts`
    59
    60
        /// @dev Approve to arbitrary address, uses Actor by default
    61
        /// NOTE: You're almost always better off setting approvals in `Setup`
    62
        function asset_approve(address to, uint128 amt) private asActor {
    63
            MockERC20(_getAsset()).approve(to, amt);
    64
        }
    65
    66
        /// @dev Mint to arbitrary address, uses owner by default, even though MockERC20 doesn't check
    67
        function asset_mint(address to, uint128 amt) private asAdmin {
    68
            MockERC20(_getAsset()).mint(to, amt);
    69
        }
    70
    }