/opt/scfuzzbench/work/target/contracts/contracts/echidna/Debugger.sol
  1 |     | // SPDX-License-Identifier: BUSL-1.1
  2 |     | pragma solidity ^0.8.0;
  3 |     | 
  4 |     | library Debugger {
  5 |     |     event Debug(string debugString);
  6 |     |     event Debug(string description, string data);
  7 |     |     event Debug(string prefix, string description, string data);
  8 |     |     event Debug(string description, bytes32 data);
  9 |     |     event Debug(string prefix, string description, bytes32 data);
 10 |     |     event Debug(string description, uint256 data);
 11 |     |     event Debug(string prefix, string description, uint256 data);
 12 |     |     event Debug(string description, int256 data);
 13 |     |     event Debug(string prefix, string description, int256 data);
 14 |     |     event Debug(string description, address data);
 15 |     |     event Debug(string prefix, string description, address data);
 16 |     |     event Debug(string description, bool data);
 17 |     |     event Debug(string prefix, string description, bool data);
 18 |     | 
 19 |     |     function log(string memory debugString) internal {
 20 |     |         emit Debug(debugString);
 21 |     |     }
 22 |     | 
 23 |     |     function log(string memory description, string memory data) internal {
 24 |     |         emit Debug(description, data);
 25 |     |     }
 26 |     | 
 27 |     |     function log(
 28 |     |         string memory prefix,
 29 |     |         string memory description,
 30 |     |         string memory data
 31 |     |     ) internal {
 32 |     |         emit Debug(prefix, description, data);
 33 |     |     }
 34 |     | 
 35 |     |     function log(string memory description, bytes32 data) internal {
 36 |     |         emit Debug(description, data);
 37 |     |     }
 38 |     | 
 39 |     |     function log(
 40 |     |         string memory prefix,
 41 |     |         string memory description,
 42 |     |         bytes32 data
 43 |     |     ) internal {
 44 |     |         emit Debug(prefix, description, data);
 45 |     |     }
 46 |     | 
 47 | *   |     function log(string memory description, uint256 data) internal {
 48 | *   |         emit Debug(description, data);
 49 |     |     }
 50 |     | 
 51 |     |     function log(
 52 |     |         string memory prefix,
 53 |     |         string memory description,
 54 |     |         uint256 data
 55 |     |     ) internal {
 56 |     |         emit Debug(prefix, description, data);
 57 |     |     }
 58 |     | 
 59 | *   |     function log(string memory description, int256 data) internal {
 60 | *   |         emit Debug(description, data);
 61 |     |     }
 62 |     | 
 63 |     |     function log(
 64 |     |         string memory prefix,
 65 |     |         string memory description,
 66 |     |         int256 data
 67 |     |     ) internal {
 68 |     |         emit Debug(prefix, description, data);
 69 |     |     }
 70 |     | 
 71 |     |     function log(string memory description, address data) internal {
 72 |     |         emit Debug(description, data);
 73 |     |     }
 74 |     | 
 75 |     |     function log(
 76 |     |         string memory prefix,
 77 |     |         string memory description,
 78 |     |         address data
 79 |     |     ) internal {
 80 |     |         emit Debug(prefix, description, data);
 81 |     |     }
 82 |     | 
 83 |     |     function log(string memory description, bool data) internal {
 84 |     |         emit Debug(description, data);
 85 |     |     }
 86 |     | 
 87 |     |     function log(
 88 |     |         string memory prefix,
 89 |     |         string memory description,
 90 |     |         bool data
 91 |     |     ) internal {
 92 |     |         emit Debug(prefix, description, data);
 93 |     |     }
 94 |     | }
 95 |     | 

/opt/scfuzzbench/work/target/contracts/contracts/echidna/Echidna.sol
  1 |     | // SPDX-License-Identifier: BUSL-1.1
  2 |     | pragma solidity ^0.8.0;
  3 |     | 
  4 |     | import "./EchidnaTestApproval.sol";
  5 |     | 
  6 |     | /**
  7 |     |  * @title Echidna test contract for OUSD
  8 |     |  * @notice Target contract to be tested, containing all mixins
  9 |     |  * @author Rappie
 10 |     |  */
 11 |     | contract Echidna is EchidnaTestApproval {
 12 |     | 
 13 |     | }
 14 |     | 

/opt/scfuzzbench/work/target/contracts/contracts/echidna/EchidnaConfig.sol
   1 |     | // SPDX-License-Identifier: BUSL-1.1
   2 |     | pragma solidity ^0.8.0;
   3 |     | 
   4 |     | /**
   5 |     |  * @title Top-level mixin for configuring the desired fuzzing setup
   6 |     |  * @author Rappie
   7 |     |  */
   8 | *   | contract EchidnaConfig {
   9 | *   |     address internal constant ADDRESS_VAULT = address(0x10000);
  10 | *   |     address internal constant ADDRESS_OUTSIDER_USER = address(0x20000);
  11 |     | 
  12 | *   |     address internal constant ADDRESS_USER0 = address(0x30000);
  13 | *   |     address internal constant ADDRESS_USER1 = address(0x40000);
  14 |     | 
  15 |     |     // Will be set in EchidnaSetup constructor
  16 |     |     address internal ADDRESS_OUTSIDER_CONTRACT;
  17 |     |     address internal ADDRESS_CONTRACT0;
  18 |     |     address internal ADDRESS_CONTRACT1;
  19 |     | 
  20 |     |     // Toggle known issues
  21 |     |     //
  22 |     |     // This can be used to skip tests that are known to fail. This is useful
  23 |     |     // when debugging a specific issue, but should be disabled when running
  24 |     |     // the full test suite.
  25 |     |     //
  26 |     |     //   True => skip tests that are known to fail
  27 |     |     //   False => run all tests
  28 |     |     //
  29 |     |     bool internal constant TOGGLE_KNOWN_ISSUES = false;
  30 |     | 
  31 |     |     // Toggle known issues within limits
  32 |     |     //
  33 |     |     // Same as TOGGLE_KNOWN_ISSUES, but also skip tests that are known to fail
  34 |     |     // within limits set by the variables below.
  35 |     |     //
  36 |     |     bool internal constant TOGGLE_KNOWN_ISSUES_WITHIN_LIMITS = false;
  37 |     | 
  38 |     |     // Starting balance
  39 |     |     //
  40 |     |     // Gives OUSD a non-zero starting supply, which can be useful to ignore
  41 |     |     // certain edge cases.
  42 |     |     //
  43 |     |     // The starting balance is given to outsider accounts that are not used as
  44 |     |     // accounts while fuzzing.
  45 |     |     //
  46 |     |     bool internal constant TOGGLE_STARTING_BALANCE = true;
  47 | *   |     uint256 internal constant STARTING_BALANCE = 1_000_000e18;
  48 |     | 
  49 |     |     // Change supply
  50 |     |     //
  51 |     |     // Set a limit to the amount of change per rebase, which can be useful to
  52 |     |     // ignore certain edge cases.
  53 |     |     //
  54 |     |     //  True => limit the amount of change to a percentage of total supply
  55 |     |     //  False => no limit
  56 |     |     //
  57 |     |     bool internal constant TOGGLE_CHANGESUPPLY_LIMIT = true;
  58 | *   |     uint256 internal constant CHANGESUPPLY_DIVISOR = 10; // 10% of total supply
  59 |     | 
  60 |     |     // Mint limit
  61 |     |     //
  62 |     |     // Set a limit the amount minted per mint, which can be useful to
  63 |     |     // ignore certain edge cases.
  64 |     |     //
  65 |     |     //  True => limit the amount of minted tokens
  66 |     |     //  False => no limit
  67 |     |     //
  68 |     |     bool internal constant TOGGLE_MINT_LIMIT = true;
  69 | *   |     uint256 internal constant MINT_MODULO = 1_000_000_000_000e18;
  70 |     | 
  71 |     |     // Known rounding errors
  72 | *   |     uint256 internal constant TRANSFER_ROUNDING_ERROR = 1e18 - 1;
  73 | *   |     uint256 internal constant OPT_IN_ROUNDING_ERROR = 1e18 - 1;
  74 | *   |     uint256 internal constant MINT_ROUNDING_ERROR = 1e18 - 1;
  75 |     | 
  76 |     |     /**
  77 |     |      * @notice Modifier to skip tests that are known to fail
  78 |     |      * @dev see TOGGLE_KNOWN_ISSUES for more information
  79 |     |      */
  80 |     |     modifier hasKnownIssue() {
  81 |     |         if (TOGGLE_KNOWN_ISSUES) return;
  82 | *   |         _;
  83 |     |     }
  84 |     | 
  85 |     |     /**
  86 |     |      * @notice Modifier to skip tests that are known to fail within limits
  87 |     |      * @dev see TOGGLE_KNOWN_ISSUES_WITHIN_LIMITS for more information
  88 |     |      */
  89 |     |     modifier hasKnownIssueWithinLimits() {
  90 |     |         if (TOGGLE_KNOWN_ISSUES_WITHIN_LIMITS) return;
  91 |     |         _;
  92 |     |     }
  93 |     | 
  94 |     |     /**
  95 |     |      * @notice Translate an account ID to an address
  96 |     |      * @param accountId The ID of the account
  97 |     |      * @return account The address of the account
  98 |     |      */
  99 | *   |     function getAccount(uint8 accountId)
 100 |     |         internal
 101 |     |         view
 102 | *   |         returns (address account)
 103 |     |     {
 104 | *   |         accountId = accountId / 64;
 105 | *   |         if (accountId == 0) return account = ADDRESS_USER0;
 106 | *   |         if (accountId == 1) return account = ADDRESS_USER1;
 107 | *   |         if (accountId == 2) return account = ADDRESS_CONTRACT0;
 108 | *   |         if (accountId == 3) return account = ADDRESS_CONTRACT1;
 109 | *   |         require(false, "Unknown account ID");
 110 |     |     }
 111 |     | }
 112 |     | 

/opt/scfuzzbench/work/target/contracts/contracts/echidna/EchidnaDebug.sol
  1 |     | // SPDX-License-Identifier: BUSL-1.1
  2 |     | pragma solidity ^0.8.0;
  3 |     | 
  4 |     | import { Address } from "@openzeppelin/contracts/utils/Address.sol";
  5 |     | 
  6 |     | import "./EchidnaHelper.sol";
  7 |     | import "./Debugger.sol";
  8 |     | 
  9 |     | import "../token/OUSD.sol";
 10 |     | 
 11 |     | /**
 12 |     |  * @title Room for random debugging functions
 13 |     |  * @author Rappie
 14 |     |  */
 15 |     | contract EchidnaDebug is EchidnaHelper {
 16 |     |     function debugOUSD() public pure {
 17 |     |         // assert(ousd.balanceOf(ADDRESS_USER0) == 1000);
 18 |     |         // assert(ousd.rebaseState(ADDRESS_USER0) != OUSD.RebaseOptions.OptIn);
 19 |     |         // assert(Address.isContract(ADDRESS_CONTRACT0));
 20 |     |         // Debugger.log("nonRebasingSupply", ousd.nonRebasingSupply());
 21 |     |         // assert(false);
 22 |     |     }
 23 |     | }
 24 |     | 

/opt/scfuzzbench/work/target/contracts/contracts/echidna/EchidnaHelper.sol
   1 |     | // SPDX-License-Identifier: BUSL-1.1
   2 |     | pragma solidity ^0.8.0;
   3 |     | 
   4 |     | import "./EchidnaSetup.sol";
   5 |     | import "./Debugger.sol";
   6 |     | 
   7 |     | /**
   8 |     |  * @title Mixin containing helper functions
   9 |     |  * @author Rappie
  10 |     |  */
  11 |     | contract EchidnaHelper is EchidnaSetup {
  12 |     |     /**
  13 |     |      * @notice Mint tokens to an account
  14 |     |      * @param toAcc Account to mint to
  15 |     |      * @param amount Amount to mint
  16 |     |      * @return Amount minted (in case of capped mint with modulo)
  17 |     |      */
  18 | *   |     function mint(uint8 toAcc, uint256 amount) public returns (uint256) {
  19 | *   |         address to = getAccount(toAcc);
  20 |     | 
  21 |     |         if (TOGGLE_MINT_LIMIT) {
  22 | *   |             amount = amount % MINT_MODULO;
  23 |     |         }
  24 |     | 
  25 | *   |         hevm.prank(ADDRESS_VAULT);
  26 | *r  |         ousd.mint(to, amount);
  27 |     | 
  28 | *   |         return amount;
  29 |     |     }
  30 |     | 
  31 |     |     /**
  32 |     |      * @notice Burn tokens from an account
  33 |     |      * @param fromAcc Account to burn from
  34 |     |      * @param amount Amount to burn
  35 |     |      */
  36 | *   |     function burn(uint8 fromAcc, uint256 amount) public {
  37 | *   |         address from = getAccount(fromAcc);
  38 | *   |         hevm.prank(ADDRESS_VAULT);
  39 | *r  |         ousd.burn(from, amount);
  40 |     |     }
  41 |     | 
  42 |     |     /**
  43 |     |      * @notice Change the total supply of OUSD (rebase)
  44 |     |      * @param amount New total supply
  45 |     |      */
  46 | *   |     function changeSupply(uint256 amount) public {
  47 |     |         if (TOGGLE_CHANGESUPPLY_LIMIT) {
  48 | *   |             amount =
  49 | *   |                 ousd.totalSupply() +
  50 | *   |                 (amount % (ousd.totalSupply() / CHANGESUPPLY_DIVISOR));
  51 |     |         }
  52 |     | 
  53 | *   |         hevm.prank(ADDRESS_VAULT);
  54 | *   |         ousd.changeSupply(amount);
  55 |     |     }
  56 |     | 
  57 |     |     /**
  58 |     |      * @notice Transfer tokens between accounts
  59 |     |      * @param fromAcc Account to transfer from
  60 |     |      * @param toAcc Account to transfer to
  61 |     |      * @param amount Amount to transfer
  62 |     |      */
  63 | *   |     function transfer(
  64 |     |         uint8 fromAcc,
  65 |     |         uint8 toAcc,
  66 |     |         uint256 amount
  67 |     |     ) public {
  68 | *   |         address from = getAccount(fromAcc);
  69 | *   |         address to = getAccount(toAcc);
  70 | *   |         hevm.prank(from);
  71 |     |         // slither-disable-next-line unchecked-transfer
  72 | *r  |         ousd.transfer(to, amount);
  73 |     |     }
  74 |     | 
  75 |     |     /**
  76 |     |      * @notice Transfer approved tokens between accounts
  77 |     |      * @param authorizedAcc Account that is authorized to transfer
  78 |     |      * @param fromAcc Account to transfer from
  79 |     |      * @param toAcc Account to transfer to
  80 |     |      * @param amount Amount to transfer
  81 |     |      */
  82 | *   |     function transferFrom(
  83 |     |         uint8 authorizedAcc,
  84 |     |         uint8 fromAcc,
  85 |     |         uint8 toAcc,
  86 |     |         uint256 amount
  87 | *   |     ) public {
  88 | *   |         address authorized = getAccount(authorizedAcc);
  89 | *   |         address from = getAccount(fromAcc);
  90 | *   |         address to = getAccount(toAcc);
  91 | *   |         hevm.prank(authorized);
  92 |     |         // slither-disable-next-line unchecked-transfer
  93 | *r  |         ousd.transferFrom(from, to, amount);
  94 |     |     }
  95 |     | 
  96 |     |     /**
  97 |     |      * @notice Opt in to rebasing
  98 |     |      * @param targetAcc Account to opt in
  99 |     |      */
 100 | *   |     function optIn(uint8 targetAcc) public {
 101 | *   |         address target = getAccount(targetAcc);
 102 | *   |         hevm.prank(target);
 103 | *   |         ousd.rebaseOptIn();
 104 |     |     }
 105 |     | 
 106 |     |     /**
 107 |     |      * @notice Opt out of rebasing
 108 |     |      * @param targetAcc Account to opt out
 109 |     |      */
 110 | *   |     function optOut(uint8 targetAcc) public {
 111 | *   |         address target = getAccount(targetAcc);
 112 | *   |         hevm.prank(target);
 113 | *r  |         ousd.rebaseOptOut();
 114 |     |     }
 115 |     | 
 116 |     |     /**
 117 |     |      * @notice Approve an account to spend OUSD
 118 |     |      * @param ownerAcc Account that owns the OUSD
 119 |     |      * @param spenderAcc Account that is approved to spend the OUSD
 120 |     |      * @param amount Amount to approve
 121 |     |      */
 122 | *   |     function approve(
 123 |     |         uint8 ownerAcc,
 124 |     |         uint8 spenderAcc,
 125 |     |         uint256 amount
 126 |     |     ) public {
 127 | *   |         address owner = getAccount(ownerAcc);
 128 | *   |         address spender = getAccount(spenderAcc);
 129 | *   |         hevm.prank(owner);
 130 |     |         // slither-disable-next-line unused-return
 131 | *   |         ousd.approve(spender, amount);
 132 |     |     }
 133 |     | 
 134 |     |     /**
 135 |     |      * @notice Get the sum of all OUSD balances
 136 |     |      * @return total Total balance
 137 |     |      */
 138 | *   |     function getTotalBalance() public view returns (uint256 total) {
 139 | *   |         total += ousd.balanceOf(ADDRESS_VAULT);
 140 | *   |         total += ousd.balanceOf(ADDRESS_OUTSIDER_USER);
 141 | *   |         total += ousd.balanceOf(ADDRESS_OUTSIDER_CONTRACT);
 142 | *   |         total += ousd.balanceOf(ADDRESS_USER0);
 143 | *   |         total += ousd.balanceOf(ADDRESS_USER1);
 144 | *   |         total += ousd.balanceOf(ADDRESS_CONTRACT0);
 145 | *   |         total += ousd.balanceOf(ADDRESS_CONTRACT1);
 146 |     |     }
 147 |     | 
 148 |     |     /**
 149 |     |      * @notice Get the sum of all non-rebasing OUSD balances
 150 |     |      * @return total Total balance
 151 |     |      */
 152 | *   |     function getTotalNonRebasingBalance() public returns (uint256 total) {
 153 | *   |         total += ousd._isNonRebasingAccountEchidna(ADDRESS_VAULT)
 154 | *   |             ? ousd.balanceOf(ADDRESS_VAULT)
 155 | *   |             : 0;
 156 | *   |         total += ousd._isNonRebasingAccountEchidna(ADDRESS_OUTSIDER_USER)
 157 | *   |             ? ousd.balanceOf(ADDRESS_OUTSIDER_USER)
 158 | *   |             : 0;
 159 | *   |         total += ousd._isNonRebasingAccountEchidna(ADDRESS_OUTSIDER_CONTRACT)
 160 | *   |             ? ousd.balanceOf(ADDRESS_OUTSIDER_CONTRACT)
 161 |     |             : 0;
 162 | *   |         total += ousd._isNonRebasingAccountEchidna(ADDRESS_USER0)
 163 | *   |             ? ousd.balanceOf(ADDRESS_USER0)
 164 | *   |             : 0;
 165 | *   |         total += ousd._isNonRebasingAccountEchidna(ADDRESS_USER1)
 166 | *   |             ? ousd.balanceOf(ADDRESS_USER1)
 167 | *   |             : 0;
 168 | *   |         total += ousd._isNonRebasingAccountEchidna(ADDRESS_CONTRACT0)
 169 | *   |             ? ousd.balanceOf(ADDRESS_CONTRACT0)
 170 | *   |             : 0;
 171 | *   |         total += ousd._isNonRebasingAccountEchidna(ADDRESS_CONTRACT1)
 172 | *   |             ? ousd.balanceOf(ADDRESS_CONTRACT1)
 173 | *   |             : 0;
 174 |     |     }
 175 |     | }
 176 |     | 

/opt/scfuzzbench/work/target/contracts/contracts/echidna/EchidnaSetup.sol
  1 |     | // SPDX-License-Identifier: BUSL-1.1
  2 |     | pragma solidity ^0.8.0;
  3 |     | 
  4 |     | import "./IHevm.sol";
  5 |     | import "./EchidnaConfig.sol";
  6 |     | import "./OUSDEchidna.sol";
  7 |     | 
  8 | *   | contract Dummy {}
  9 |     | 
 10 |     | /**
 11 |     |  * @title Mixin for setup and deployment
 12 |     |  * @author Rappie
 13 |     |  */
 14 | *   | contract EchidnaSetup is EchidnaConfig {
 15 | *   |     IHevm hevm = IHevm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
 16 | *   |     OUSDEchidna ousd = new OUSDEchidna();
 17 |     | 
 18 |     |     /**
 19 |     |      * @notice Deploy the OUSD contract and set up initial state
 20 |     |      */
 21 | *   |     constructor() {
 22 | *   |         ousd.initialize(ADDRESS_VAULT, 1e18);
 23 |     | 
 24 |     |         // Deploy dummny contracts as users
 25 | *   |         Dummy outsider = new Dummy();
 26 | *   |         ADDRESS_OUTSIDER_CONTRACT = address(outsider);
 27 | *   |         Dummy dummy0 = new Dummy();
 28 | *   |         ADDRESS_CONTRACT0 = address(dummy0);
 29 | *   |         Dummy dummy1 = new Dummy();
 30 | *   |         ADDRESS_CONTRACT1 = address(dummy1);
 31 |     | 
 32 |     |         // Start out with a reasonable amount of OUSD
 33 |     |         if (TOGGLE_STARTING_BALANCE) {
 34 |     |             // Rebasing tokens
 35 | *   |             hevm.prank(ADDRESS_VAULT);
 36 | *   |             ousd.mint(ADDRESS_OUTSIDER_USER, STARTING_BALANCE / 2);
 37 |     | 
 38 |     |             // Non-rebasing tokens
 39 | *   |             hevm.prank(ADDRESS_VAULT);
 40 | *   |             ousd.mint(ADDRESS_OUTSIDER_CONTRACT, STARTING_BALANCE / 2);
 41 |     |         }
 42 |     |     }
 43 |     | }
 44 |     | 

/opt/scfuzzbench/work/target/contracts/contracts/echidna/EchidnaTestAccounting.sol
   1 |     | // SPDX-License-Identifier: BUSL-1.1
   2 |     | pragma solidity ^0.8.0;
   3 |     | 
   4 |     | import "./EchidnaDebug.sol";
   5 |     | import "./EchidnaTestSupply.sol";
   6 |     | 
   7 |     | /**
   8 |     |  * @title Mixin for testing accounting functions
   9 |     |  * @author Rappie
  10 |     |  */
  11 |     | contract EchidnaTestAccounting is EchidnaTestSupply {
  12 |     |     /**
  13 |     |      * @notice After opting in, balance should not increase. (Ok to lose rounding funds doing this)
  14 |     |      * @param targetAcc Account to opt in
  15 |     |      */
  16 | *   |     function testOptInBalance(uint8 targetAcc) public {
  17 | *   |         address target = getAccount(targetAcc);
  18 |     | 
  19 | *   |         uint256 balanceBefore = ousd.balanceOf(target);
  20 | *   |         optIn(targetAcc);
  21 | *   |         uint256 balanceAfter = ousd.balanceOf(target);
  22 |     | 
  23 | *   |         assert(balanceAfter <= balanceBefore);
  24 |     |     }
  25 |     | 
  26 |     |     /**
  27 |     |      * @notice After opting out, balance should remain the same
  28 |     |      * @param targetAcc Account to opt out
  29 |     |      */
  30 | *   |     function testOptOutBalance(uint8 targetAcc) public {
  31 | *   |         address target = getAccount(targetAcc);
  32 |     | 
  33 | *   |         uint256 balanceBefore = ousd.balanceOf(target);
  34 | *   |         optOut(targetAcc);
  35 | *   |         uint256 balanceAfter = ousd.balanceOf(target);
  36 |     | 
  37 |     |         assert(balanceAfter == balanceBefore);
  38 |     |     }
  39 |     | 
  40 |     |     /**
  41 |     |      * @notice Account balance should remain the same after opting in minus rounding error
  42 |     |      * @param targetAcc Account to opt in
  43 |     |      */
  44 | *   |     function testOptInBalanceRounding(uint8 targetAcc) public {
  45 | *   |         address target = getAccount(targetAcc);
  46 |     | 
  47 | *   |         uint256 balanceBefore = ousd.balanceOf(target);
  48 | *   |         optIn(targetAcc);
  49 | *   |         uint256 balanceAfter = ousd.balanceOf(target);
  50 |     | 
  51 | *   |         int256 delta = int256(balanceAfter) - int256(balanceBefore);
  52 | *   |         Debugger.log("delta", delta);
  53 |     | 
  54 |     |         // slither-disable-next-line tautology
  55 | *   |         assert(-1 * delta >= 0);
  56 | *   |         assert(-1 * delta <= int256(OPT_IN_ROUNDING_ERROR));
  57 |     |     }
  58 |     | 
  59 |     |     /**
  60 |     |      * @notice After opting in, total supply should remain the same
  61 |     |      * @param targetAcc Account to opt in
  62 |     |      */
  63 | *   |     function testOptInTotalSupply(uint8 targetAcc) public {
  64 | *   |         uint256 totalSupplyBefore = ousd.totalSupply();
  65 | *   |         optIn(targetAcc);
  66 |     |         uint256 totalSupplyAfter = ousd.totalSupply();
  67 |     | 
  68 |     |         assert(totalSupplyAfter == totalSupplyBefore);
  69 |     |     }
  70 |     | 
  71 |     |     /**
  72 |     |      * @notice After opting out, total supply should remain the same
  73 |     |      * @param targetAcc Account to opt out
  74 |     |      */
  75 | *   |     function testOptOutTotalSupply(uint8 targetAcc) public {
  76 | *   |         uint256 totalSupplyBefore = ousd.totalSupply();
  77 | *   |         optOut(targetAcc);
  78 | *   |         uint256 totalSupplyAfter = ousd.totalSupply();
  79 |     | 
  80 | *   |         assert(totalSupplyAfter == totalSupplyBefore);
  81 |     |     }
  82 |     | 
  83 |     |     /**
  84 |     |      * @notice Account balance should remain the same when a smart contract auto converts
  85 |     |      * @param targetAcc Account to auto convert
  86 |     |      */
  87 | *   |     function testAutoConvertBalance(uint8 targetAcc) public {
  88 | *   |         address target = getAccount(targetAcc);
  89 |     | 
  90 | *   |         uint256 balanceBefore = ousd.balanceOf(target);
  91 |     |         // slither-disable-next-line unused-return
  92 | *   |         ousd._isNonRebasingAccountEchidna(target);
  93 | *   |         uint256 balanceAfter = ousd.balanceOf(target);
  94 |     | 
  95 | *   |         assert(balanceAfter == balanceBefore);
  96 |     |     }
  97 |     | 
  98 |     |     /**
  99 |     |      * @notice The `balanceOf` function should never revert
 100 |     |      * @param targetAcc Account to check balance of
 101 |     |      */
 102 | *   |     function testBalanceOfShouldNotRevert(uint8 targetAcc) public {
 103 | *   |         address target = getAccount(targetAcc);
 104 |     | 
 105 |     |         // slither-disable-next-line unused-return
 106 | *   |         try ousd.balanceOf(target) {
 107 |     |             assert(true);
 108 |     |         } catch {
 109 |     |             assert(false);
 110 |     |         }
 111 |     |     }
 112 |     | }
 113 |     | 

/opt/scfuzzbench/work/target/contracts/contracts/echidna/EchidnaTestApproval.sol
  1 |     | // SPDX-License-Identifier: BUSL-1.1
  2 |     | pragma solidity ^0.8.0;
  3 |     | 
  4 |     | import "./EchidnaTestMintBurn.sol";
  5 |     | import "./Debugger.sol";
  6 |     | 
  7 |     | /**
  8 |     |  * @title Mixin for testing approval related functions
  9 |     |  * @author Rappie
 10 |     |  */
 11 |     | contract EchidnaTestApproval is EchidnaTestMintBurn {
 12 |     |     /**
 13 |     |      * @notice Performing `transferFrom` with an amount inside the allowance should not revert
 14 |     |      * @param authorizedAcc The account that is authorized to transfer
 15 |     |      * @param fromAcc The account that is transferring
 16 |     |      * @param toAcc The account that is receiving
 17 |     |      * @param amount The amount to transfer
 18 |     |      */
 19 | *   |     function testTransferFromShouldNotRevert(
 20 |     |         uint8 authorizedAcc,
 21 |     |         uint8 fromAcc,
 22 |     |         uint8 toAcc,
 23 |     |         uint256 amount
 24 |     |     ) public {
 25 | *   |         address authorized = getAccount(authorizedAcc);
 26 | *   |         address from = getAccount(fromAcc);
 27 | *   |         address to = getAccount(toAcc);
 28 |     | 
 29 | *r  |         require(amount <= ousd.balanceOf(from));
 30 | *r  |         require(amount <= ousd.allowance(from, authorized));
 31 |     | 
 32 | *   |         hevm.prank(authorized);
 33 |     |         // slither-disable-next-line unchecked-transfer
 34 | *   |         try ousd.transferFrom(from, to, amount) {
 35 |     |             // pass
 36 |     |         } catch {
 37 |     |             assert(false);
 38 |     |         }
 39 |     |     }
 40 |     | 
 41 |     |     /**
 42 |     |      * @notice Performing `transferFrom` with an amount outside the allowance should revert
 43 |     |      * @param authorizedAcc The account that is authorized to transfer
 44 |     |      * @param fromAcc The account that is transferring
 45 |     |      * @param toAcc The account that is receiving
 46 |     |      * @param amount The amount to transfer
 47 |     |      */
 48 | *   |     function testTransferFromShouldRevert(
 49 |     |         uint8 authorizedAcc,
 50 |     |         uint8 fromAcc,
 51 |     |         uint8 toAcc,
 52 |     |         uint256 amount
 53 | *   |     ) public {
 54 | *   |         address authorized = getAccount(authorizedAcc);
 55 | *   |         address from = getAccount(fromAcc);
 56 | *   |         address to = getAccount(toAcc);
 57 |     | 
 58 | *r  |         require(amount > 0);
 59 | *r  |         require(
 60 | *   |             !(amount <= ousd.balanceOf(from) &&
 61 | *   |                 amount <= ousd.allowance(from, authorized))
 62 |     |         );
 63 |     | 
 64 | *   |         hevm.prank(authorized);
 65 |     |         // slither-disable-next-line unchecked-transfer
 66 | *   |         try ousd.transferFrom(from, to, amount) {
 67 | *   |             assert(false);
 68 |     |         } catch {
 69 |     |             // pass
 70 |     |         }
 71 |     |     }
 72 |     | 
 73 |     |     /**
 74 |     |      * @notice Approving an amount should update the allowance and overwrite any previous allowance
 75 |     |      * @param ownerAcc The account that is approving
 76 |     |      * @param spenderAcc The account that is being approved
 77 |     |      * @param amount The amount to approve
 78 |     |      */
 79 | *   |     function testApprove(
 80 |     |         uint8 ownerAcc,
 81 |     |         uint8 spenderAcc,
 82 |     |         uint256 amount
 83 |     |     ) public {
 84 | *   |         address owner = getAccount(ownerAcc);
 85 | *   |         address spender = getAccount(spenderAcc);
 86 |     | 
 87 | *   |         approve(ownerAcc, spenderAcc, amount);
 88 | *   |         uint256 allowanceAfter1 = ousd.allowance(owner, spender);
 89 |     | 
 90 | *   |         assert(allowanceAfter1 == amount);
 91 |     | 
 92 | *   |         approve(ownerAcc, spenderAcc, amount / 2);
 93 | *   |         uint256 allowanceAfter2 = ousd.allowance(owner, spender);
 94 |     | 
 95 | *   |         assert(allowanceAfter2 == amount / 2);
 96 |     |     }
 97 |     | }
 98 |     | 

/opt/scfuzzbench/work/target/contracts/contracts/echidna/EchidnaTestMintBurn.sol
   1 |     | // SPDX-License-Identifier: BUSL-1.1
   2 |     | pragma solidity ^0.8.0;
   3 |     | 
   4 |     | import "./EchidnaDebug.sol";
   5 |     | import "./EchidnaTestAccounting.sol";
   6 |     | 
   7 |     | /**
   8 |     |  * @title Mixin for testing Mint and Burn functions
   9 |     |  * @author Rappie
  10 |     |  */
  11 |     | contract EchidnaTestMintBurn is EchidnaTestAccounting {
  12 |     |     /**
  13 |     |      * @notice Minting 0 tokens should not affect account balance
  14 |     |      * @param targetAcc Account to mint to
  15 |     |      */
  16 | *   |     function testMintZeroBalance(uint8 targetAcc) public {
  17 | *   |         address target = getAccount(targetAcc);
  18 |     | 
  19 | *   |         uint256 balanceBefore = ousd.balanceOf(target);
  20 | *   |         mint(targetAcc, 0);
  21 |     |         uint256 balanceAfter = ousd.balanceOf(target);
  22 |     | 
  23 |     |         assert(balanceAfter == balanceBefore);
  24 |     |     }
  25 |     | 
  26 |     |     /**
  27 |     |      * @notice Burning 0 tokens should not affect account balance
  28 |     |      * @param targetAcc Account to burn from
  29 |     |      */
  30 | *   |     function testBurnZeroBalance(uint8 targetAcc) public {
  31 | *   |         address target = getAccount(targetAcc);
  32 |     | 
  33 | *   |         uint256 balanceBefore = ousd.balanceOf(target);
  34 | *   |         burn(targetAcc, 0);
  35 |     |         uint256 balanceAfter = ousd.balanceOf(target);
  36 |     | 
  37 |     |         assert(balanceAfter == balanceBefore);
  38 |     |     }
  39 |     | 
  40 |     |     /**
  41 |     |      * @notice Minting tokens must increase the account balance by at least amount
  42 |     |      * @param targetAcc Account to mint to
  43 |     |      * @param amount Amount to mint
  44 |     |      * @custom:error testMintBalance(uint8,uint256): failed!💥
  45 |     |      *   Call sequence:
  46 |     |      *       changeSupply(1)
  47 |     |      *       testMintBalance(0,1)
  48 |     |      *   Event sequence:
  49 |     |      *       Debug(«balanceBefore», 0)
  50 |     |      *       Debug(«balanceAfter», 0)
  51 |     |      */
  52 | *   |     function testMintBalance(uint8 targetAcc, uint256 amount)
  53 |     |         public
  54 |     |         hasKnownIssue
  55 |     |         hasKnownIssueWithinLimits
  56 |     |     {
  57 | *   |         address target = getAccount(targetAcc);
  58 |     | 
  59 | *   |         uint256 balanceBefore = ousd.balanceOf(target);
  60 | *   |         uint256 amountMinted = mint(targetAcc, amount);
  61 | *   |         uint256 balanceAfter = ousd.balanceOf(target);
  62 |     | 
  63 | *   |         Debugger.log("amountMinted", amountMinted);
  64 | *   |         Debugger.log("balanceBefore", balanceBefore);
  65 | *   |         Debugger.log("balanceAfter", balanceAfter);
  66 |     | 
  67 | *   |         assert(balanceAfter >= balanceBefore + amountMinted);
  68 |     |     }
  69 |     | 
  70 |     |     /**
  71 |     |      * @notice Burning tokens must decrease the account balance by at least amount
  72 |     |      * @param targetAcc Account to burn from
  73 |     |      * @param amount Amount to burn
  74 |     |      * @custom:error testBurnBalance(uint8,uint256): failed!💥
  75 |     |      *   Call sequence:
  76 |     |      *       changeSupply(1)
  77 |     |      *       mint(0,3)
  78 |     |      *       testBurnBalance(0,1)
  79 |     |      *   Event sequence:
  80 |     |      *       Debug(«balanceBefore», 2)
  81 |     |      *       Debug(«balanceAfter», 2)
  82 |     |      */
  83 | *   |     function testBurnBalance(uint8 targetAcc, uint256 amount)
  84 |     |         public
  85 |     |         hasKnownIssue
  86 |     |         hasKnownIssueWithinLimits
  87 |     |     {
  88 | *   |         address target = getAccount(targetAcc);
  89 |     | 
  90 | *   |         uint256 balanceBefore = ousd.balanceOf(target);
  91 | *   |         burn(targetAcc, amount);
  92 | *   |         uint256 balanceAfter = ousd.balanceOf(target);
  93 |     | 
  94 | *   |         Debugger.log("balanceBefore", balanceBefore);
  95 | *   |         Debugger.log("balanceAfter", balanceAfter);
  96 |     | 
  97 | *   |         assert(balanceAfter <= balanceBefore - amount);
  98 |     |     }
  99 |     | 
 100 |     |     /**
 101 |     |      * @notice Minting tokens should not increase the account balance by less than rounding error above amount
 102 |     |      * @param targetAcc Account to mint to
 103 |     |      * @param amount Amount to mint
 104 |     |      */
 105 | *   |     function testMintBalanceRounding(uint8 targetAcc, uint256 amount) public {
 106 | *   |         address target = getAccount(targetAcc);
 107 |     | 
 108 | *   |         uint256 balanceBefore = ousd.balanceOf(target);
 109 | *   |         uint256 amountMinted = mint(targetAcc, amount);
 110 | *   |         uint256 balanceAfter = ousd.balanceOf(target);
 111 |     | 
 112 | *   |         int256 delta = int256(balanceAfter) - int256(balanceBefore);
 113 |     | 
 114 |     |         // delta == amount, if no error
 115 |     |         // delta < amount,  if too little is minted
 116 |     |         // delta > amount,  if too much is minted
 117 | *   |         int256 error = int256(amountMinted) - delta;
 118 |     | 
 119 | *   |         assert(error >= 0);
 120 | *   |         assert(error <= int256(MINT_ROUNDING_ERROR));
 121 |     |     }
 122 |     | 
 123 |     |     /**
 124 |     |      * @notice A burn of an account balance must result in a zero balance
 125 |     |      * @param targetAcc Account to burn from
 126 |     |      */
 127 | *   |     function testBurnAllBalanceToZero(uint8 targetAcc) public hasKnownIssue {
 128 | *   |         address target = getAccount(targetAcc);
 129 |     | 
 130 | *   |         burn(targetAcc, ousd.balanceOf(target));
 131 | *   |         assert(ousd.balanceOf(target) == 0);
 132 |     |     }
 133 |     | 
 134 |     |     /**
 135 |     |      * @notice You should always be able to burn an account's balance
 136 |     |      * @param targetAcc Account to burn from
 137 |     |      */
 138 | *   |     function testBurnAllBalanceShouldNotRevert(uint8 targetAcc)
 139 |     |         public
 140 |     |         hasKnownIssue
 141 |     |     {
 142 | *   |         address target = getAccount(targetAcc);
 143 | *   |         uint256 balance = ousd.balanceOf(target);
 144 |     | 
 145 | *   |         hevm.prank(ADDRESS_VAULT);
 146 | *   |         try ousd.burn(target, balance) {
 147 |     |             assert(true);
 148 |     |         } catch {
 149 |     |             assert(false);
 150 |     |         }
 151 |     |     }
 152 |     | }
 153 |     | 

/opt/scfuzzbench/work/target/contracts/contracts/echidna/EchidnaTestSupply.sol
   1 |     | // SPDX-License-Identifier: BUSL-1.1
   2 |     | pragma solidity ^0.8.0;
   3 |     | 
   4 |     | import "./EchidnaDebug.sol";
   5 |     | import "./EchidnaTestTransfer.sol";
   6 |     | 
   7 |     | import { StableMath } from "../utils/StableMath.sol";
   8 |     | 
   9 |     | /**
  10 |     |  * @title Mixin for testing supply related functions
  11 |     |  * @author Rappie
  12 |     |  */
  13 |     | contract EchidnaTestSupply is EchidnaTestTransfer {
  14 |     |     using StableMath for uint256;
  15 |     | 
  16 | *   |     uint256 prevRebasingCreditsPerToken = type(uint256).max;
  17 |     | 
  18 |     |     /**
  19 |     |      * @notice After a `changeSupply`, the total supply should exactly
  20 |     |      * match the target total supply. (This is needed to ensure successive
  21 |     |      * rebases are correct).
  22 |     |      * @param supply New total supply
  23 |     |      * @custom:error testChangeSupply(uint256): failed!💥
  24 |     |      *   Call sequence:
  25 |     |      *       testChangeSupply(1044505275072865171609)
  26 |     |      *   Event sequence:
  27 |     |      *       TotalSupplyUpdatedHighres(1044505275072865171610, 1000000000000000000000000, 957391048054055578595)
  28 |     |      */
  29 | *   |     function testChangeSupply(uint256 supply)
  30 |     |         public
  31 |     |         hasKnownIssue
  32 |     |         hasKnownIssueWithinLimits
  33 |     |     {
  34 | *   |         hevm.prank(ADDRESS_VAULT);
  35 | *r  |         ousd.changeSupply(supply);
  36 |     | 
  37 | *   |         assert(ousd.totalSupply() == supply);
  38 |     |     }
  39 |     | 
  40 |     |     /**
  41 |     |      * @notice The total supply must not be less than the sum of account balances.
  42 |     |      * (The difference will go into future rebases)
  43 |     |      * @custom:error testTotalSupplyLessThanTotalBalance(): failed!💥
  44 |     |      *   Call sequence:
  45 |     |      *     mint(0,1)
  46 |     |      *     changeSupply(1)
  47 |     |      *     optOut(64)
  48 |     |      *     transfer(0,64,1)
  49 |     |      *     testTotalSupplyLessThanTotalBalance()
  50 |     |      *   Event sequence:
  51 |     |      *     Debug(«totalSupply», 1000000000000000001000001)
  52 |     |      *     Debug(«totalBalance», 1000000000000000001000002)
  53 |     |      */
  54 | *   |     function testTotalSupplyLessThanTotalBalance()
  55 |     |         public
  56 |     |         hasKnownIssue
  57 |     |         hasKnownIssueWithinLimits
  58 |     |     {
  59 | *   |         uint256 totalSupply = ousd.totalSupply();
  60 | *   |         uint256 totalBalance = getTotalBalance();
  61 |     | 
  62 | *   |         Debugger.log("totalSupply", totalSupply);
  63 | *   |         Debugger.log("totalBalance", totalBalance);
  64 |     | 
  65 |     |         assert(totalSupply >= totalBalance);
  66 |     |     }
  67 |     | 
  68 |     |     /**
  69 |     |      * @notice Non-rebasing supply should not be larger than total supply
  70 |     |      * @custom:error testNonRebasingSupplyVsTotalSupply(): failed!💥
  71 |     |      *   Call sequence:
  72 |     |      *     mint(0,2)
  73 |     |      *     changeSupply(3)
  74 |     |      *     burn(0,1)
  75 |     |      *     optOut(0)
  76 |     |      *     testNonRebasingSupplyVsTotalSupply()
  77 |     |      */
  78 | *   |     function testNonRebasingSupplyVsTotalSupply() public hasKnownIssue {
  79 | *   |         uint256 nonRebasingSupply = ousd.nonRebasingSupply();
  80 | *   |         uint256 totalSupply = ousd.totalSupply();
  81 |     | 
  82 | *   |         assert(nonRebasingSupply <= totalSupply);
  83 |     |     }
  84 |     | 
  85 |     |     /**
  86 |     |      * @notice Global `rebasingCreditsPerToken` should never increase
  87 |     |      * @custom:error testRebasingCreditsPerTokenNotIncreased(): failed!💥
  88 |     |      *   Call sequence:
  89 |     |      *     testRebasingCreditsPerTokenNotIncreased()
  90 |     |      *     changeSupply(1)
  91 |     |      *     testRebasingCreditsPerTokenNotIncreased()
  92 |     |      */
  93 | *   |     function testRebasingCreditsPerTokenNotIncreased() public hasKnownIssue {
  94 | *   |         uint256 curRebasingCreditsPerToken = ousd
  95 |     |             .rebasingCreditsPerTokenHighres();
  96 |     | 
  97 | *   |         Debugger.log(
  98 |     |             "prevRebasingCreditsPerToken",
  99 | *   |             prevRebasingCreditsPerToken
 100 |     |         );
 101 | *   |         Debugger.log("curRebasingCreditsPerToken", curRebasingCreditsPerToken);
 102 |     | 
 103 | *   |         assert(curRebasingCreditsPerToken <= prevRebasingCreditsPerToken);
 104 |     | 
 105 | *   |         prevRebasingCreditsPerToken = curRebasingCreditsPerToken;
 106 |     |     }
 107 |     | 
 108 |     |     /**
 109 |     |      * @notice The rebasing credits per token ratio must greater than zero
 110 |     |      */
 111 | *   |     function testRebasingCreditsPerTokenAboveZero() public {
 112 | *   |         assert(ousd.rebasingCreditsPerTokenHighres() > 0);
 113 |     |     }
 114 |     | 
 115 |     |     /**
 116 |     |      * @notice The sum of all non-rebasing balances should not be larger than
 117 |     |      * non-rebasing supply
 118 |     |      * @custom:error testTotalNonRebasingSupplyLessThanTotalBalance(): failed!💥
 119 |     |      *   Call sequence
 120 |     |      *     mint(0,2)
 121 |     |      *     changeSupply(1)
 122 |     |      *     optOut(0)
 123 |     |      *     burn(0,1)
 124 |     |      *     testTotalNonRebasingSupplyLessThanTotalBalance()
 125 |     |      *   Event sequence:
 126 |     |      *     Debug(«totalNonRebasingSupply», 500000000000000000000001)
 127 |     |      *     Debug(«totalNonRebasingBalance», 500000000000000000000002)
 128 |     |      */
 129 | *   |     function testTotalNonRebasingSupplyLessThanTotalBalance()
 130 |     |         public
 131 |     |         hasKnownIssue
 132 |     |         hasKnownIssueWithinLimits
 133 |     |     {
 134 | *   |         uint256 totalNonRebasingSupply = ousd.nonRebasingSupply();
 135 | *   |         uint256 totalNonRebasingBalance = getTotalNonRebasingBalance();
 136 |     | 
 137 | *   |         Debugger.log("totalNonRebasingSupply", totalNonRebasingSupply);
 138 | *   |         Debugger.log("totalNonRebasingBalance", totalNonRebasingBalance);
 139 |     | 
 140 | *   |         assert(totalNonRebasingSupply >= totalNonRebasingBalance);
 141 |     |     }
 142 |     | 
 143 |     |     /**
 144 |     |      * @notice An accounts credits / credits per token should not be larger it's balance
 145 |     |      * @param targetAcc The account to check
 146 |     |      */
 147 | *   |     function testCreditsPerTokenVsBalance(uint8 targetAcc) public {
 148 | *   |         address target = getAccount(targetAcc);
 149 |     | 
 150 | *   |         (uint256 credits, uint256 creditsPerToken, ) = ousd
 151 |     |             .creditsBalanceOfHighres(target);
 152 | *   |         uint256 expectedBalance = credits.divPrecisely(creditsPerToken);
 153 |     | 
 154 | *   |         uint256 balance = ousd.balanceOf(target);
 155 |     | 
 156 | *   |         Debugger.log("credits", credits);
 157 | *   |         Debugger.log("creditsPerToken", creditsPerToken);
 158 | *   |         Debugger.log("expectedBalance", expectedBalance);
 159 | *   |         Debugger.log("balance", balance);
 160 |     | 
 161 | *   |         assert(expectedBalance == balance);
 162 |     |     }
 163 |     | }
 164 |     | 

/opt/scfuzzbench/work/target/contracts/contracts/echidna/EchidnaTestTransfer.sol
   1 |     | // SPDX-License-Identifier: BUSL-1.1
   2 |     | pragma solidity ^0.8.0;
   3 |     | 
   4 |     | import "./EchidnaDebug.sol";
   5 |     | import "./Debugger.sol";
   6 |     | 
   7 |     | /**
   8 |     |  * @title Mixin for testing transfer related functions
   9 |     |  * @author Rappie
  10 |     |  */
  11 |     | contract EchidnaTestTransfer is EchidnaDebug {
  12 |     |     /**
  13 |     |      * @notice The receiving account's balance after a transfer must not increase by
  14 |     |      * less than the amount transferred
  15 |     |      * @param fromAcc Account to transfer from
  16 |     |      * @param toAcc Account to transfer to
  17 |     |      * @param amount Amount to transfer
  18 |     |      * @custom:error testTransferBalanceReceivedLess(uint8,uint8,uint256): failed!💥
  19 |     |      *   Call sequence:
  20 |     |      *     changeSupply(1)
  21 |     |      *     mint(64,2)
  22 |     |      *     testTransferBalanceReceivedLess(64,0,1)
  23 |     |      *   Event sequence:
  24 |     |      *     Debug(«totalSupply», 1000000000000000000500002)
  25 |     |      *     Debug(«toBalBefore», 0)
  26 |     |      *     Debug(«toBalAfter», 0)
  27 |     |      */
  28 | *   |     function testTransferBalanceReceivedLess(
  29 |     |         uint8 fromAcc,
  30 |     |         uint8 toAcc,
  31 |     |         uint256 amount
  32 |     |     ) public hasKnownIssue hasKnownIssueWithinLimits {
  33 | *   |         address from = getAccount(fromAcc);
  34 | *   |         address to = getAccount(toAcc);
  35 |     | 
  36 | *r  |         require(from != to);
  37 |     | 
  38 | *   |         uint256 toBalBefore = ousd.balanceOf(to);
  39 | *   |         transfer(fromAcc, toAcc, amount);
  40 | *   |         uint256 toBalAfter = ousd.balanceOf(to);
  41 |     | 
  42 | *   |         Debugger.log("totalSupply", ousd.totalSupply());
  43 | *   |         Debugger.log("toBalBefore", toBalBefore);
  44 | *   |         Debugger.log("toBalAfter", toBalAfter);
  45 |     | 
  46 | *   |         assert(toBalAfter >= toBalBefore + amount);
  47 |     |     }
  48 |     | 
  49 |     |     /**
  50 |     |      * @notice The receiving account's balance after a transfer must not
  51 |     |      * increase by more than the amount transferred
  52 |     |      * @param fromAcc Account to transfer from
  53 |     |      * @param toAcc Account to transfer to
  54 |     |      * @param amount Amount to transfer
  55 |     |      */
  56 | *   |     function testTransferBalanceReceivedMore(
  57 |     |         uint8 fromAcc,
  58 |     |         uint8 toAcc,
  59 |     |         uint256 amount
  60 |     |     ) public {
  61 | *   |         address from = getAccount(fromAcc);
  62 | *   |         address to = getAccount(toAcc);
  63 |     | 
  64 | *r  |         require(from != to);
  65 |     | 
  66 | *   |         uint256 toBalBefore = ousd.balanceOf(to);
  67 | *   |         transfer(fromAcc, toAcc, amount);
  68 | *   |         uint256 toBalAfter = ousd.balanceOf(to);
  69 |     | 
  70 | *   |         Debugger.log("totalSupply", ousd.totalSupply());
  71 | *   |         Debugger.log("toBalBefore", toBalBefore);
  72 | *   |         Debugger.log("toBalAfter", toBalAfter);
  73 |     | 
  74 | *   |         assert(toBalAfter <= toBalBefore + amount);
  75 |     |     }
  76 |     | 
  77 |     |     /**
  78 |     |      * @notice The sending account's balance after a transfer must not
  79 |     |      * decrease by less than the amount transferred
  80 |     |      * @param fromAcc Account to transfer from
  81 |     |      * @param toAcc Account to transfer to
  82 |     |      * @param amount Amount to transfer
  83 |     |      * @custom:error testTransferBalanceSentLess(uint8,uint8,uint256): failed!💥
  84 |     |      *   Call sequence:
  85 |     |      *     mint(0,1)
  86 |     |      *     changeSupply(1)
  87 |     |      *     testTransferBalanceSentLess(0,64,1)
  88 |     |      *   Event sequence:
  89 |     |      *     Debug(«totalSupply», 1000000000000000000500001)
  90 |     |      *     Debug(«fromBalBefore», 1)
  91 |     |      *     Debug(«fromBalAfter», 1)
  92 |     |      */
  93 | *   |     function testTransferBalanceSentLess(
  94 |     |         uint8 fromAcc,
  95 |     |         uint8 toAcc,
  96 |     |         uint256 amount
  97 |     |     ) public hasKnownIssue hasKnownIssueWithinLimits {
  98 | *   |         address from = getAccount(fromAcc);
  99 | *   |         address to = getAccount(toAcc);
 100 |     | 
 101 | *r  |         require(from != to);
 102 |     | 
 103 | *   |         uint256 fromBalBefore = ousd.balanceOf(from);
 104 | *   |         transfer(fromAcc, toAcc, amount);
 105 | *   |         uint256 fromBalAfter = ousd.balanceOf(from);
 106 |     | 
 107 | *   |         Debugger.log("totalSupply", ousd.totalSupply());
 108 | *   |         Debugger.log("fromBalBefore", fromBalBefore);
 109 | *   |         Debugger.log("fromBalAfter", fromBalAfter);
 110 |     | 
 111 | *   |         assert(fromBalAfter <= fromBalBefore - amount);
 112 |     |     }
 113 |     | 
 114 |     |     /**
 115 |     |      * @notice The sending account's balance after a transfer must not
 116 |     |      * decrease by more than the amount transferred
 117 |     |      * @param fromAcc Account to transfer from
 118 |     |      * @param toAcc Account to transfer to
 119 |     |      * @param amount Amount to transfer
 120 |     |      */
 121 | *   |     function testTransferBalanceSentMore(
 122 |     |         uint8 fromAcc,
 123 |     |         uint8 toAcc,
 124 |     |         uint256 amount
 125 |     |     ) public {
 126 | *   |         address from = getAccount(fromAcc);
 127 | *   |         address to = getAccount(toAcc);
 128 |     | 
 129 | *r  |         require(from != to);
 130 |     | 
 131 | *   |         uint256 fromBalBefore = ousd.balanceOf(from);
 132 | *   |         transfer(fromAcc, toAcc, amount);
 133 | *   |         uint256 fromBalAfter = ousd.balanceOf(from);
 134 |     | 
 135 | *   |         Debugger.log("totalSupply", ousd.totalSupply());
 136 | *   |         Debugger.log("fromBalBefore", fromBalBefore);
 137 | *   |         Debugger.log("fromBalAfter", fromBalAfter);
 138 |     | 
 139 | *   |         assert(fromBalAfter >= fromBalBefore - amount);
 140 |     |     }
 141 |     | 
 142 |     |     /**
 143 |     |      * @notice The receiving account's balance after a transfer must not
 144 |     |      * increase by less than the amount transferred (minus rounding error)
 145 |     |      * @param fromAcc Account to transfer from
 146 |     |      * @param toAcc Account to transfer to
 147 |     |      * @param amount Amount to transfer
 148 |     |      */
 149 | *   |     function testTransferBalanceReceivedLessRounding(
 150 |     |         uint8 fromAcc,
 151 |     |         uint8 toAcc,
 152 |     |         uint256 amount
 153 | *   |     ) public {
 154 | *   |         address from = getAccount(fromAcc);
 155 | *   |         address to = getAccount(toAcc);
 156 |     | 
 157 | *r  |         require(from != to);
 158 |     | 
 159 | *   |         uint256 toBalBefore = ousd.balanceOf(to);
 160 | *   |         transfer(fromAcc, toAcc, amount);
 161 | *   |         uint256 toBalAfter = ousd.balanceOf(to);
 162 |     | 
 163 | *   |         int256 toDelta = int256(toBalAfter) - int256(toBalBefore);
 164 |     | 
 165 |     |         // delta == amount, if no error
 166 |     |         // delta < amount,  if too little is sent
 167 |     |         // delta > amount,  if too much is sent
 168 | *   |         int256 error = int256(amount) - toDelta;
 169 |     | 
 170 | *   |         Debugger.log("totalSupply", ousd.totalSupply());
 171 | *   |         Debugger.log("toBalBefore", toBalBefore);
 172 | *   |         Debugger.log("toBalAfter", toBalAfter);
 173 | *   |         Debugger.log("toDelta", toDelta);
 174 | *   |         Debugger.log("error", error);
 175 |     | 
 176 | *   |         assert(error >= 0);
 177 | *   |         assert(error <= int256(TRANSFER_ROUNDING_ERROR));
 178 |     |     }
 179 |     | 
 180 |     |     /**
 181 |     |      * @notice The sending account's balance after a transfer must
 182 |     |      * not decrease by less than the amount transferred (minus rounding error)
 183 |     |      * @param fromAcc Account to transfer from
 184 |     |      * @param toAcc Account to transfer to
 185 |     |      * @param amount Amount to transfer
 186 |     |      */
 187 | *   |     function testTransferBalanceSentLessRounding(
 188 |     |         uint8 fromAcc,
 189 |     |         uint8 toAcc,
 190 |     |         uint256 amount
 191 |     |     ) public {
 192 | *   |         address from = getAccount(fromAcc);
 193 | *   |         address to = getAccount(toAcc);
 194 |     | 
 195 | *r  |         require(from != to);
 196 |     | 
 197 | *   |         uint256 fromBalBefore = ousd.balanceOf(from);
 198 | *   |         transfer(fromAcc, toAcc, amount);
 199 | *   |         uint256 fromBalAfter = ousd.balanceOf(from);
 200 |     | 
 201 | *   |         int256 fromDelta = int256(fromBalAfter) - int256(fromBalBefore);
 202 |     | 
 203 |     |         // delta == -amount, if no error
 204 |     |         // delta < -amount,  if too much is sent
 205 |     |         // delta > -amount,  if too little is sent
 206 | *   |         int256 error = int256(amount) + fromDelta;
 207 |     | 
 208 | *   |         Debugger.log("totalSupply", ousd.totalSupply());
 209 | *   |         Debugger.log("fromBalBefore", fromBalBefore);
 210 | *   |         Debugger.log("fromBalAfter", fromBalAfter);
 211 | *   |         Debugger.log("fromDelta", fromDelta);
 212 |     |         Debugger.log("error", error);
 213 |     | 
 214 |     |         assert(error >= 0);
 215 |     |         assert(error <= int256(TRANSFER_ROUNDING_ERROR));
 216 |     |     }
 217 |     | 
 218 |     |     /**
 219 |     |      * @notice An account should always be able to successfully transfer
 220 |     |      * an amount within its balance.
 221 |     |      * @param fromAcc Account to transfer from
 222 |     |      * @param toAcc Account to transfer to
 223 |     |      * @param amount Amount to transfer
 224 |     |      * @custom:error testTransferWithinBalanceDoesNotRevert(uint8,uint8,uint8): failed!💥
 225 |     |      *   Call sequence:
 226 |     |      *       mint(0,1)
 227 |     |      *       changeSupply(3)
 228 |     |      *       optOut(0)
 229 |     |      *       testTransferWithinBalanceDoesNotRevert(0,128,2)
 230 |     |      *       optIn(0)
 231 |     |      *       testTransferWithinBalanceDoesNotRevert(128,0,1)
 232 |     |      *   Event sequence:
 233 |     |      *       error Revert Panic(17): SafeMath over-/under-flows
 234 |     |      */
 235 | *   |     function testTransferWithinBalanceDoesNotRevert(
 236 |     |         uint8 fromAcc,
 237 |     |         uint8 toAcc,
 238 |     |         uint256 amount
 239 | *   |     ) public hasKnownIssue {
 240 | *   |         address from = getAccount(fromAcc);
 241 | *   |         address to = getAccount(toAcc);
 242 |     | 
 243 | *r  |         require(amount > 0);
 244 | *   |         amount = amount % ousd.balanceOf(from);
 245 |     | 
 246 | *   |         Debugger.log("Total supply", ousd.totalSupply());
 247 |     | 
 248 | *   |         hevm.prank(from);
 249 |     |         // slither-disable-next-line unchecked-transfer
 250 | *   |         try ousd.transfer(to, amount) {
 251 | *   |             assert(true);
 252 |     |         } catch {
 253 | *   |             assert(false);
 254 |     |         }
 255 |     |     }
 256 |     | 
 257 |     |     /**
 258 |     |      * @notice An account should never be able to successfully transfer
 259 |     |      * an amount greater than their balance.
 260 |     |      * @param fromAcc Account to transfer from
 261 |     |      * @param toAcc Account to transfer to
 262 |     |      * @param amount Amount to transfer
 263 |     |      */
 264 | *   |     function testTransferExceedingBalanceReverts(
 265 |     |         uint8 fromAcc,
 266 |     |         uint8 toAcc,
 267 |     |         uint256 amount
 268 |     |     ) public {
 269 | *   |         address from = getAccount(fromAcc);
 270 | *   |         address to = getAccount(toAcc);
 271 |     | 
 272 | *   |         amount = ousd.balanceOf(from) + 1 + amount;
 273 |     | 
 274 | *   |         hevm.prank(from);
 275 |     |         // slither-disable-next-line unchecked-transfer
 276 | *   |         try ousd.transfer(to, amount) {
 277 |     |             assert(false);
 278 |     |         } catch {
 279 | *   |             assert(true);
 280 |     |         }
 281 |     |     }
 282 |     | 
 283 |     |     /**
 284 |     |      * @notice A transfer to the same account should not change that account's balance
 285 |     |      * @param targetAcc Account to transfer to
 286 |     |      * @param amount Amount to transfer
 287 |     |      */
 288 | *   |     function testTransferSelf(uint8 targetAcc, uint256 amount) public {
 289 | *   |         address target = getAccount(targetAcc);
 290 |     | 
 291 | *   |         uint256 balanceBefore = ousd.balanceOf(target);
 292 | *   |         transfer(targetAcc, targetAcc, amount);
 293 | *   |         uint256 balanceAfter = ousd.balanceOf(target);
 294 |     | 
 295 | *   |         assert(balanceBefore == balanceAfter);
 296 |     |     }
 297 |     | 
 298 |     |     /**
 299 |     |      * @notice Transfers to the zero account revert
 300 |     |      * @param fromAcc Account to transfer from
 301 |     |      * @param amount Amount to transfer
 302 |     |      */
 303 | *   |     function testTransferToZeroAddress(uint8 fromAcc, uint256 amount) public {
 304 | *   |         address from = getAccount(fromAcc);
 305 |     | 
 306 | *   |         hevm.prank(from);
 307 |     |         // slither-disable-next-line unchecked-transfer
 308 | *   |         try ousd.transfer(address(0), amount) {
 309 |     |             assert(false);
 310 |     |         } catch {
 311 | *   |             assert(true);
 312 |     |         }
 313 |     |     }
 314 |     | }
 315 |     | 

/opt/scfuzzbench/work/target/contracts/contracts/echidna/IHevm.sol
  1 |     | // SPDX-License-Identifier: BUSL-1.1
  2 |     | pragma solidity ^0.8.0;
  3 |     | 
  4 |     | // https://github.com/ethereum/hevm/blob/main/doc/src/controlling-the-unit-testing-environment.md#cheat-codes
  5 |     | 
  6 |     | interface IHevm {
  7 |     |     function warp(uint256 x) external;
  8 |     | 
  9 |     |     function roll(uint256 x) external;
 10 |     | 
 11 |     |     function store(
 12 |     |         address c,
 13 |     |         bytes32 loc,
 14 |     |         bytes32 val
 15 |     |     ) external;
 16 |     | 
 17 |     |     function load(address c, bytes32 loc) external returns (bytes32 val);
 18 |     | 
 19 |     |     function sign(uint256 sk, bytes32 digest)
 20 |     |         external
 21 |     |         returns (
 22 |     |             uint8 v,
 23 |     |             bytes32 r,
 24 |     |             bytes32 s
 25 |     |         );
 26 |     | 
 27 |     |     function addr(uint256 sk) external returns (address addr);
 28 |     | 
 29 |     |     function ffi(string[] calldata) external returns (bytes memory);
 30 |     | 
 31 |     |     function prank(address sender) external;
 32 |     | }
 33 |     | 

/opt/scfuzzbench/work/target/contracts/contracts/echidna/OUSDEchidna.sol
  1 |     | // SPDX-License-Identifier: BUSL-1.1
  2 |     | pragma solidity ^0.8.0;
  3 |     | 
  4 |     | import "../token/OUSD.sol";
  5 |     | 
  6 | *   | contract OUSDEchidna is OUSD {
  7 | *   |     constructor() OUSD() {
  8 |     |         // The Yield Delegation rewrite (#2298) left Governable without a
  9 |     |         // constructor, so the governor slot is zero and the harness could
 10 |     |         // never call initialize() (onlyGovernor). Make the deploying harness
 11 |     |         // the governor so the suite is runnable again.
 12 | *   |         _setGovernor(msg.sender);
 13 |     |     }
 14 |     | 
 15 | *   |     function _isNonRebasingAccountEchidna(address _account)
 16 |     |         public
 17 | *   |         returns (bool)
 18 |     |     {
 19 | *   |         _autoMigrate(_account);
 20 | *   |         return alternativeCreditsPerToken[_account] > 0;
 21 |     |     }
 22 |     | }
 23 |     | 

/opt/scfuzzbench/work/target/contracts/contracts/governance/Governable.sol
   1 |     | // SPDX-License-Identifier: BUSL-1.1
   2 |     | pragma solidity ^0.8.0;
   3 |     | 
   4 |     | /**
   5 |     |  * @title Base for contracts that are managed by the Origin Protocol's Governor.
   6 |     |  * @dev Copy of the openzeppelin Ownable.sol contract with nomenclature change
   7 |     |  *      from owner to governor and renounce methods removed. Does not use
   8 |     |  *      Context.sol like Ownable.sol does for simplification.
   9 |     |  * @author Origin Protocol Inc
  10 |     |  */
  11 |     | abstract contract Governable {
  12 |     |     // Storage position of the owner and pendingOwner of the contract
  13 |     |     // keccak256("OUSD.governor");
  14 |     |     bytes32 private constant governorPosition =
  15 |     |         0x7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a;
  16 |     | 
  17 |     |     // keccak256("OUSD.pending.governor");
  18 |     |     bytes32 private constant pendingGovernorPosition =
  19 |     |         0x44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db;
  20 |     | 
  21 |     |     // keccak256("OUSD.reentry.status");
  22 |     |     bytes32 private constant reentryStatusPosition =
  23 |     |         0x53bf423e48ed90e97d02ab0ebab13b2a235a6bfbe9c321847d5c175333ac4535;
  24 |     | 
  25 |     |     // See OpenZeppelin ReentrancyGuard implementation
  26 |     |     uint256 constant _NOT_ENTERED = 1;
  27 |     |     uint256 constant _ENTERED = 2;
  28 |     | 
  29 |     |     event PendingGovernorshipTransfer(
  30 |     |         address indexed previousGovernor,
  31 |     |         address indexed newGovernor
  32 |     |     );
  33 |     | 
  34 |     |     event GovernorshipTransferred(
  35 |     |         address indexed previousGovernor,
  36 |     |         address indexed newGovernor
  37 |     |     );
  38 |     | 
  39 |     |     /**
  40 |     |      * @notice Returns the address of the current Governor.
  41 |     |      */
  42 |     |     function governor() public view returns (address) {
  43 |     |         return _governor();
  44 |     |     }
  45 |     | 
  46 |     |     /**
  47 |     |      * @dev Returns the address of the current Governor.
  48 |     |      */
  49 | *   |     function _governor() internal view returns (address governorOut) {
  50 |     |         bytes32 position = governorPosition;
  51 |     |         // solhint-disable-next-line no-inline-assembly
  52 |     |         assembly {
  53 | *   |             governorOut := sload(position)
  54 |     |         }
  55 |     |     }
  56 |     | 
  57 |     |     /**
  58 |     |      * @dev Returns the address of the pending Governor.
  59 |     |      */
  60 |     |     function _pendingGovernor()
  61 |     |         internal
  62 |     |         view
  63 |     |         returns (address pendingGovernor)
  64 |     |     {
  65 |     |         bytes32 position = pendingGovernorPosition;
  66 |     |         // solhint-disable-next-line no-inline-assembly
  67 |     |         assembly {
  68 |     |             pendingGovernor := sload(position)
  69 |     |         }
  70 |     |     }
  71 |     | 
  72 |     |     /**
  73 |     |      * @dev Throws if called by any account other than the Governor.
  74 |     |      */
  75 |     |     modifier onlyGovernor() {
  76 | *   |         require(isGovernor(), "Caller is not the Governor");
  77 |     |         _;
  78 |     |     }
  79 |     | 
  80 |     |     /**
  81 |     |      * @notice Returns true if the caller is the current Governor.
  82 |     |      */
  83 | *   |     function isGovernor() public view returns (bool) {
  84 | *   |         return msg.sender == _governor();
  85 |     |     }
  86 |     | 
  87 | *   |     function _setGovernor(address newGovernor) internal {
  88 | *   |         emit GovernorshipTransferred(_governor(), newGovernor);
  89 |     | 
  90 |     |         bytes32 position = governorPosition;
  91 |     |         // solhint-disable-next-line no-inline-assembly
  92 |     |         assembly {
  93 | *   |             sstore(position, newGovernor)
  94 |     |         }
  95 |     |     }
  96 |     | 
  97 |     |     /**
  98 |     |      * @dev Prevents a contract from calling itself, directly or indirectly.
  99 |     |      * Calling a `nonReentrant` function from another `nonReentrant`
 100 |     |      * function is not supported. It is possible to prevent this from happening
 101 |     |      * by making the `nonReentrant` function external, and make it call a
 102 |     |      * `private` function that does the actual work.
 103 |     |      */
 104 |     |     modifier nonReentrant() {
 105 |     |         bytes32 position = reentryStatusPosition;
 106 |     |         uint256 _reentry_status;
 107 |     |         // solhint-disable-next-line no-inline-assembly
 108 |     |         assembly {
 109 |     |             _reentry_status := sload(position)
 110 |     |         }
 111 |     | 
 112 |     |         // On the first call to nonReentrant, _notEntered will be true
 113 |     |         require(_reentry_status != _ENTERED, "Reentrant call");
 114 |     | 
 115 |     |         // Any calls to nonReentrant after this point will fail
 116 |     |         // solhint-disable-next-line no-inline-assembly
 117 |     |         assembly {
 118 |     |             sstore(position, _ENTERED)
 119 |     |         }
 120 |     | 
 121 |     |         _;
 122 |     | 
 123 |     |         // By storing the original value once again, a refund is triggered (see
 124 |     |         // https://eips.ethereum.org/EIPS/eip-2200)
 125 |     |         // solhint-disable-next-line no-inline-assembly
 126 |     |         assembly {
 127 |     |             sstore(position, _NOT_ENTERED)
 128 |     |         }
 129 |     |     }
 130 |     | 
 131 |     |     function _setPendingGovernor(address newGovernor) internal {
 132 |     |         bytes32 position = pendingGovernorPosition;
 133 |     |         // solhint-disable-next-line no-inline-assembly
 134 |     |         assembly {
 135 |     |             sstore(position, newGovernor)
 136 |     |         }
 137 |     |     }
 138 |     | 
 139 |     |     /**
 140 |     |      * @notice Transfers Governance of the contract to a new account (`newGovernor`).
 141 |     |      * Can only be called by the current Governor. Must be claimed for this to complete
 142 |     |      * @param _newGovernor Address of the new Governor
 143 |     |      */
 144 |     |     function transferGovernance(address _newGovernor) external onlyGovernor {
 145 |     |         _setPendingGovernor(_newGovernor);
 146 |     |         emit PendingGovernorshipTransfer(_governor(), _newGovernor);
 147 |     |     }
 148 |     | 
 149 |     |     /**
 150 |     |      * @notice Claim Governance of the contract to a new account (`newGovernor`).
 151 |     |      * Can only be called by the new Governor.
 152 |     |      */
 153 | *   |     function claimGovernance() external {
 154 |     |         require(
 155 |     |             msg.sender == _pendingGovernor(),
 156 |     |             "Only the pending Governor can complete the claim"
 157 |     |         );
 158 | *   |         _changeGovernor(msg.sender);
 159 |     |     }
 160 |     | 
 161 |     |     /**
 162 |     |      * @dev Change Governance of the contract to a new account (`newGovernor`).
 163 |     |      * @param _newGovernor Address of the new Governor
 164 |     |      */
 165 |     |     function _changeGovernor(address _newGovernor) internal {
 166 |     |         require(_newGovernor != address(0), "New Governor is address(0)");
 167 |     |         _setGovernor(_newGovernor);
 168 |     |     }
 169 |     | }
 170 |     | 

/opt/scfuzzbench/work/target/contracts/contracts/interfaces/IBasicToken.sol
  1 |     | // SPDX-License-Identifier: MIT
  2 |     | pragma solidity ^0.8.0;
  3 |     | 
  4 |     | interface IBasicToken {
  5 |     |     function symbol() external view returns (string memory);
  6 |     | 
  7 |     |     function decimals() external view returns (uint8);
  8 |     | }
  9 |     | 

/opt/scfuzzbench/work/target/contracts/contracts/interfaces/IStrategy.sol
  1 |     | // SPDX-License-Identifier: BUSL-1.1
  2 |     | pragma solidity ^0.8.0;
  3 |     | 
  4 |     | /**
  5 |     |  * @title Platform interface to integrate with lending platform like Compound, AAVE etc.
  6 |     |  */
  7 |     | interface IStrategy {
  8 |     |     /**
  9 |     |      * @dev Deposit the given asset to platform
 10 |     |      * @param _asset asset address
 11 |     |      * @param _amount Amount to deposit
 12 |     |      */
 13 |     |     function deposit(address _asset, uint256 _amount) external;
 14 |     | 
 15 |     |     /**
 16 |     |      * @dev Deposit the entire balance of all supported assets in the Strategy
 17 |     |      *      to the platform
 18 |     |      */
 19 |     |     function depositAll() external;
 20 |     | 
 21 |     |     /**
 22 |     |      * @dev Withdraw given asset from Lending platform
 23 |     |      */
 24 |     |     function withdraw(
 25 |     |         address _recipient,
 26 |     |         address _asset,
 27 |     |         uint256 _amount
 28 |     |     ) external;
 29 |     | 
 30 |     |     /**
 31 |     |      * @dev Liquidate all assets in strategy and return them to Vault.
 32 |     |      */
 33 |     |     function withdrawAll() external;
 34 |     | 
 35 |     |     /**
 36 |     |      * @dev Returns the current balance of the given asset.
 37 |     |      */
 38 |     |     function checkBalance(address _asset)
 39 |     |         external
 40 |     |         view
 41 |     |         returns (uint256 balance);
 42 |     | 
 43 |     |     /**
 44 |     |      * @dev Returns bool indicating whether strategy supports asset.
 45 |     |      */
 46 |     |     function supportsAsset(address _asset) external view returns (bool);
 47 |     | 
 48 |     |     /**
 49 |     |      * @dev Collect reward tokens from the Strategy.
 50 |     |      */
 51 |     |     function collectRewardTokens() external;
 52 |     | 
 53 |     |     /**
 54 |     |      * @dev The address array of the reward tokens for the Strategy.
 55 |     |      */
 56 |     |     function getRewardTokenAddresses() external view returns (address[] memory);
 57 |     | 
 58 |     |     function harvesterAddress() external view returns (address);
 59 |     | 
 60 |     |     function transferToken(address token, uint256 amount) external;
 61 |     | 
 62 |     |     function setRewardTokenAddresses(address[] calldata _rewardTokenAddresses)
 63 |     |         external;
 64 |     | }
 65 |     | 

/opt/scfuzzbench/work/target/contracts/contracts/interfaces/IVault.sol
   1 |     | // SPDX-License-Identifier: BUSL-1.1
   2 |     | pragma solidity ^0.8.0;
   3 |     | 
   4 |     | import { VaultStorage } from "../vault/VaultStorage.sol";
   5 |     | 
   6 |     | interface IVault {
   7 |     |     // slither-disable-start constable-states
   8 |     | 
   9 |     |     event AssetAllocated(address _asset, address _strategy, uint256 _amount);
  10 |     |     event StrategyApproved(address _addr);
  11 |     |     event StrategyRemoved(address _addr);
  12 |     |     event Mint(address _addr, uint256 _value);
  13 |     |     event Redeem(address _addr, uint256 _value);
  14 |     |     event CapitalPaused();
  15 |     |     event CapitalUnpaused();
  16 |     |     event DefaultStrategyUpdated(address _strategy);
  17 |     |     event RebasePaused();
  18 |     |     event RebaseUnpaused();
  19 |     |     event VaultBufferUpdated(uint256 _vaultBuffer);
  20 |     |     event AllocateThresholdUpdated(uint256 _threshold);
  21 |     |     event StrategistUpdated(address _address);
  22 |     |     event MaxSupplyDiffChanged(uint256 maxSupplyDiff);
  23 |     |     event YieldDistribution(address _to, uint256 _yield, uint256 _fee);
  24 |     |     event TrusteeFeeBpsChanged(uint256 _basis);
  25 |     |     event TrusteeAddressChanged(address _address);
  26 |     |     event StrategyAddedToMintWhitelist(address indexed strategy);
  27 |     |     event StrategyRemovedFromMintWhitelist(address indexed strategy);
  28 |     |     event RebasePerSecondMaxChanged(uint256 rebaseRatePerSecond);
  29 |     |     event DripDurationChanged(uint256 dripDuration);
  30 |     |     event WithdrawalRequested(
  31 |     |         address indexed _withdrawer,
  32 |     |         uint256 indexed _requestId,
  33 |     |         uint256 _amount,
  34 |     |         uint256 _queued
  35 |     |     );
  36 |     |     event WithdrawalClaimed(
  37 |     |         address indexed _withdrawer,
  38 |     |         uint256 indexed _requestId,
  39 |     |         uint256 _amount
  40 |     |     );
  41 |     |     event WithdrawalClaimable(uint256 _claimable, uint256 _newClaimable);
  42 |     |     event WithdrawalClaimDelayUpdated(uint256 _newDelay);
  43 |     | 
  44 |     |     // Governable.sol
  45 |     |     function transferGovernance(address _newGovernor) external;
  46 |     | 
  47 |     |     function claimGovernance() external;
  48 |     | 
  49 |     |     function governor() external view returns (address);
  50 |     | 
  51 |     |     // VaultAdmin.sol
  52 |     |     function setVaultBuffer(uint256 _vaultBuffer) external;
  53 |     | 
  54 |     |     function vaultBuffer() external view returns (uint256);
  55 |     | 
  56 |     |     function setAutoAllocateThreshold(uint256 _threshold) external;
  57 |     | 
  58 |     |     function autoAllocateThreshold() external view returns (uint256);
  59 |     | 
  60 |     |     function setStrategistAddr(address _address) external;
  61 |     | 
  62 |     |     function strategistAddr() external view returns (address);
  63 |     | 
  64 |     |     function setOperatorAddr(address _operator) external;
  65 |     | 
  66 |     |     function operatorAddr() external view returns (address);
  67 |     | 
  68 |     |     function setMaxSupplyDiff(uint256 _maxSupplyDiff) external;
  69 |     | 
  70 |     |     function maxSupplyDiff() external view returns (uint256);
  71 |     | 
  72 |     |     function setTrusteeAddress(address _address) external;
  73 |     | 
  74 |     |     function trusteeAddress() external view returns (address);
  75 |     | 
  76 |     |     function setTrusteeFeeBps(uint256 _basis) external;
  77 |     | 
  78 |     |     function trusteeFeeBps() external view returns (uint256);
  79 |     | 
  80 |     |     function approveStrategy(address _addr) external;
  81 |     | 
  82 |     |     function removeStrategy(address _addr) external;
  83 |     | 
  84 |     |     function setDefaultStrategy(address _strategy) external;
  85 |     | 
  86 |     |     function defaultStrategy() external view returns (address);
  87 |     | 
  88 |     |     function pauseRebase() external;
  89 |     | 
  90 |     |     function unpauseRebase() external;
  91 |     | 
  92 |     |     function rebasePaused() external view returns (bool);
  93 |     | 
  94 |     |     function pauseCapital() external;
  95 |     | 
  96 |     |     function unpauseCapital() external;
  97 |     | 
  98 |     |     function capitalPaused() external view returns (bool);
  99 |     | 
 100 |     |     function transferToken(address _asset, uint256 _amount) external;
 101 |     | 
 102 |     |     function withdrawAllFromStrategy(address _strategyAddr) external;
 103 |     | 
 104 |     |     function withdrawAllFromStrategies() external;
 105 |     | 
 106 |     |     function withdrawFromStrategy(
 107 |     |         address _strategyFromAddress,
 108 |     |         address[] calldata _assets,
 109 |     |         uint256[] calldata _amounts
 110 |     |     ) external;
 111 |     | 
 112 |     |     function depositToStrategy(
 113 |     |         address _strategyToAddress,
 114 |     |         address[] calldata _assets,
 115 |     |         uint256[] calldata _amounts
 116 |     |     ) external;
 117 |     | 
 118 |     |     // VaultCore.sol
 119 |     |     function mint(uint256 _amount) external;
 120 |     | 
 121 |     |     function mintForStrategy(uint256 _amount) external;
 122 |     | 
 123 |     |     function burnForStrategy(uint256 _amount) external;
 124 |     | 
 125 |     |     function allocate() external;
 126 |     | 
 127 |     |     function rebase() external;
 128 |     | 
 129 |     |     function totalValue() external view returns (uint256 value);
 130 |     | 
 131 |     |     function checkBalance(address _asset) external view returns (uint256);
 132 |     | 
 133 |     |     function getAssetCount() external view returns (uint256);
 134 |     | 
 135 |     |     function getAllAssets() external view returns (address[] memory);
 136 |     | 
 137 |     |     function getStrategyCount() external view returns (uint256);
 138 |     | 
 139 |     |     function getAllStrategies() external view returns (address[] memory);
 140 |     | 
 141 |     |     function strategies(address _addr)
 142 |     |         external
 143 |     |         view
 144 |     |         returns (VaultStorage.Strategy memory);
 145 |     | 
 146 |     |     /// @notice Deprecated: use `asset()` instead.
 147 |     |     function isSupportedAsset(address _asset) external view returns (bool);
 148 |     | 
 149 |     |     function asset() external view returns (address);
 150 |     | 
 151 |     |     function oToken() external view returns (address);
 152 |     | 
 153 |     |     function initialize(address) external;
 154 |     | 
 155 |     |     function addWithdrawalQueueLiquidity() external;
 156 |     | 
 157 |     |     function requestWithdrawal(uint256 _amount)
 158 |     |         external
 159 |     |         returns (uint256 requestId, uint256 queued);
 160 |     | 
 161 |     |     function claimWithdrawal(uint256 requestId)
 162 |     |         external
 163 |     |         returns (uint256 amount);
 164 |     | 
 165 |     |     function claimWithdrawals(uint256[] memory requestIds)
 166 |     |         external
 167 |     |         returns (uint256[] memory amounts, uint256 totalAmount);
 168 |     | 
 169 |     |     function withdrawalQueueMetadata()
 170 |     |         external
 171 |     |         view
 172 |     |         returns (VaultStorage.WithdrawalQueueMetadata memory);
 173 |     | 
 174 |     |     function withdrawalRequests(uint256 requestId)
 175 |     |         external
 176 |     |         view
 177 |     |         returns (VaultStorage.WithdrawalRequest memory);
 178 |     | 
 179 |     |     function addStrategyToMintWhitelist(address strategyAddr) external;
 180 |     | 
 181 |     |     function removeStrategyFromMintWhitelist(address strategyAddr) external;
 182 |     | 
 183 |     |     function isMintWhitelistedStrategy(address strategyAddr)
 184 |     |         external
 185 |     |         view
 186 |     |         returns (bool);
 187 |     | 
 188 |     |     function withdrawalClaimDelay() external view returns (uint256);
 189 |     | 
 190 |     |     function setWithdrawalClaimDelay(uint256 newDelay) external;
 191 |     | 
 192 |     |     function lastRebase() external view returns (uint64);
 193 |     | 
 194 |     |     function dripDuration() external view returns (uint64);
 195 |     | 
 196 |     |     function setDripDuration(uint256 _dripDuration) external;
 197 |     | 
 198 |     |     function rebasePerSecondMax() external view returns (uint64);
 199 |     | 
 200 |     |     function setRebaseRateMax(uint256 yearlyApr) external;
 201 |     | 
 202 |     |     function rebasePerSecondTarget() external view returns (uint64);
 203 |     | 
 204 |     |     function previewYield() external view returns (uint256 yield);
 205 |     | 
 206 |     |     // slither-disable-end constable-states
 207 |     | }
 208 |     | 

/opt/scfuzzbench/work/target/contracts/contracts/token/OUSD.sol
   1 |     | // SPDX-License-Identifier: BUSL-1.1
   2 |     | pragma solidity ^0.8.0;
   3 |     | 
   4 |     | /**
   5 |     |  * @title OUSD Token Contract
   6 |     |  * @dev ERC20 compatible contract for OUSD
   7 |     |  * @dev Implements an elastic supply
   8 |     |  * @author Origin Protocol Inc
   9 |     |  */
  10 |     | import { IVault } from "../interfaces/IVault.sol";
  11 |     | import { Governable } from "../governance/Governable.sol";
  12 |     | import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";
  13 |     | 
  14 |     | contract OUSD is Governable {
  15 |     |     using SafeCast for int256;
  16 |     |     using SafeCast for uint256;
  17 |     | 
  18 |     |     /// @dev Event triggered when the supply changes
  19 |     |     /// @param totalSupply Updated token total supply
  20 |     |     /// @param rebasingCredits Updated token rebasing credits
  21 |     |     /// @param rebasingCreditsPerToken Updated token rebasing credits per token
  22 |     |     event TotalSupplyUpdatedHighres(
  23 |     |         uint256 totalSupply,
  24 |     |         uint256 rebasingCredits,
  25 |     |         uint256 rebasingCreditsPerToken
  26 |     |     );
  27 |     |     /// @dev Event triggered when an account opts in for rebasing
  28 |     |     /// @param account Address of the account
  29 |     |     event AccountRebasingEnabled(address account);
  30 |     |     /// @dev Event triggered when an account opts out of rebasing
  31 |     |     /// @param account Address of the account
  32 |     |     event AccountRebasingDisabled(address account);
  33 |     |     /// @dev Emitted when `value` tokens are moved from one account `from` to
  34 |     |     ///      another `to`.
  35 |     |     /// @param from Address of the account tokens are moved from
  36 |     |     /// @param to Address of the account tokens are moved to
  37 |     |     /// @param value Amount of tokens transferred
  38 |     |     event Transfer(address indexed from, address indexed to, uint256 value);
  39 |     |     /// @dev Emitted when the allowance of a `spender` for an `owner` is set by
  40 |     |     ///      a call to {approve}. `value` is the new allowance.
  41 |     |     /// @param owner Address of the owner approving allowance
  42 |     |     /// @param spender Address of the spender allowance is granted to
  43 |     |     /// @param value Amount of tokens spender can transfer
  44 |     |     event Approval(
  45 |     |         address indexed owner,
  46 |     |         address indexed spender,
  47 |     |         uint256 value
  48 |     |     );
  49 |     |     /// @dev Yield resulting from {changeSupply} that a `source` account would
  50 |     |     ///      receive is directed to `target` account.
  51 |     |     /// @param source Address of the source forwarding the yield
  52 |     |     /// @param target Address of the target receiving the yield
  53 |     |     event YieldDelegated(address source, address target);
  54 |     |     /// @dev Yield delegation from `source` account to the `target` account is
  55 |     |     ///      suspended.
  56 |     |     /// @param source Address of the source suspending yield forwarding
  57 |     |     /// @param target Address of the target no longer receiving yield from `source`
  58 |     |     ///        account
  59 |     |     event YieldUndelegated(address source, address target);
  60 |     | 
  61 |     |     enum RebaseOptions {
  62 |     |         NotSet,
  63 |     |         StdNonRebasing,
  64 |     |         StdRebasing,
  65 |     |         YieldDelegationSource,
  66 |     |         YieldDelegationTarget
  67 |     |     }
  68 |     | 
  69 |     |     uint256[154] private _gap; // Slots to align with deployed contract
  70 |     |     uint256 private constant MAX_SUPPLY = type(uint128).max;
  71 |     |     /// @dev The amount of tokens in existence
  72 | *   |     uint256 public totalSupply;
  73 |     |     mapping(address => mapping(address => uint256)) private allowances;
  74 |     |     /// @dev The vault with privileges to execute {mint}, {burn}
  75 |     |     ///     and {changeSupply}
  76 |     |     address public vaultAddress;
  77 |     |     mapping(address => uint256) internal creditBalances;
  78 |     |     // the 2 storage variables below need trailing underscores to not name collide with public functions
  79 |     |     uint256 private rebasingCredits_; // Sum of all rebasing credits (creditBalances for rebasing accounts)
  80 |     |     uint256 private rebasingCreditsPerToken_;
  81 |     |     /// @dev The amount of tokens that are not rebasing - receiving yield
  82 | *   |     uint256 public nonRebasingSupply;
  83 |     |     mapping(address => uint256) internal alternativeCreditsPerToken;
  84 |     |     /// @dev A map of all addresses and their respective RebaseOptions
  85 |     |     mapping(address => RebaseOptions) public rebaseState;
  86 |     |     mapping(address => uint256) private __deprecated_isUpgraded;
  87 |     |     /// @dev A map of addresses that have yields forwarded to. This is an
  88 |     |     ///      inverse mapping of {yieldFrom}
  89 |     |     /// Key Account forwarding yield
  90 |     |     /// Value Account receiving yield
  91 |     |     mapping(address => address) public yieldTo;
  92 |     |     /// @dev A map of addresses that are receiving the yield. This is an
  93 |     |     ///      inverse mapping of {yieldTo}
  94 |     |     /// Key Account receiving yield
  95 |     |     /// Value Account forwarding yield
  96 |     |     mapping(address => address) public yieldFrom;
  97 |     | 
  98 |     |     uint256 private constant RESOLUTION_INCREASE = 1e9;
  99 |     |     uint256[34] private __gap; // including below gap totals up to 200
 100 |     | 
 101 |     |     /// @dev Verifies that the caller is the Governor or Strategist.
 102 |     |     modifier onlyGovernorOrStrategist() {
 103 | *   |         require(
 104 |     |             isGovernor() || msg.sender == IVault(vaultAddress).strategistAddr(),
 105 |     |             "Caller is not the Strategist or Governor"
 106 |     |         );
 107 |     |         _;
 108 |     |     }
 109 |     | 
 110 |     |     /// @dev Initializes the contract and sets necessary variables.
 111 |     |     /// @param _vaultAddress Address of the vault contract
 112 |     |     /// @param _initialCreditsPerToken The starting rebasing credits per token.
 113 | *   |     function initialize(address _vaultAddress, uint256 _initialCreditsPerToken)
 114 |     |         external
 115 |     |         onlyGovernor
 116 |     |     {
 117 | *   |         require(_vaultAddress != address(0), "Zero vault address");
 118 | *   |         require(vaultAddress == address(0), "Already initialized");
 119 |     | 
 120 | *   |         rebasingCreditsPerToken_ = _initialCreditsPerToken;
 121 | *   |         vaultAddress = _vaultAddress;
 122 |     |     }
 123 |     | 
 124 |     |     /// @dev Returns the symbol of the token, a shorter version
 125 |     |     ///      of the name.
 126 |     |     function symbol() external pure virtual returns (string memory) {
 127 |     |         return "OUSD";
 128 |     |     }
 129 |     | 
 130 |     |     /// @dev Returns the name of the token.
 131 | *   |     function name() external pure virtual returns (string memory) {
 132 |     |         return "Origin Dollar";
 133 |     |     }
 134 |     | 
 135 |     |     /// @dev Returns the number of decimals used to get its user representation.
 136 |     |     function decimals() external pure virtual returns (uint8) {
 137 |     |         return 18;
 138 |     |     }
 139 |     | 
 140 |     |     /**
 141 |     |      * @dev Verifies that the caller is the Vault contract
 142 |     |      */
 143 |     |     modifier onlyVault() {
 144 | *   |         require(vaultAddress == msg.sender, "Caller is not the Vault");
 145 | *   |         _;
 146 |     |     }
 147 |     | 
 148 |     |     /**
 149 |     |      * @return High resolution rebasingCreditsPerToken
 150 |     |      */
 151 | *   |     function rebasingCreditsPerTokenHighres() external view returns (uint256) {
 152 | *   |         return rebasingCreditsPerToken_;
 153 |     |     }
 154 |     | 
 155 |     |     /**
 156 |     |      * @return Low resolution rebasingCreditsPerToken
 157 |     |      */
 158 |     |     function rebasingCreditsPerToken() external view returns (uint256) {
 159 |     |         return rebasingCreditsPerToken_ / RESOLUTION_INCREASE;
 160 |     |     }
 161 |     | 
 162 |     |     /**
 163 |     |      * @return High resolution total number of rebasing credits
 164 |     |      */
 165 |     |     function rebasingCreditsHighres() external view returns (uint256) {
 166 |     |         return rebasingCredits_;
 167 |     |     }
 168 |     | 
 169 |     |     /**
 170 |     |      * @return Low resolution total number of rebasing credits
 171 |     |      */
 172 | *   |     function rebasingCredits() external view returns (uint256) {
 173 |     |         return rebasingCredits_ / RESOLUTION_INCREASE;
 174 |     |     }
 175 |     | 
 176 |     |     /**
 177 |     |      * @notice Gets the balance of the specified address.
 178 |     |      * @param _account Address to query the balance of.
 179 |     |      * @return A uint256 representing the amount of base units owned by the
 180 |     |      *         specified address.
 181 |     |      */
 182 | *   |     function balanceOf(address _account) public view returns (uint256) {
 183 | *   |         RebaseOptions state = rebaseState[_account];
 184 | *   |         if (state == RebaseOptions.YieldDelegationSource) {
 185 |     |             // Saves a slot read when transferring to or from a yield delegating source
 186 |     |             // since we know creditBalances equals the balance.
 187 |     |             return creditBalances[_account];
 188 |     |         }
 189 | *   |         uint256 baseBalance = (creditBalances[_account] * 1e18) /
 190 | *   |             _creditsPerToken(_account);
 191 | *   |         if (state == RebaseOptions.YieldDelegationTarget) {
 192 |     |             // creditBalances of yieldFrom accounts equals token balances
 193 |     |             return baseBalance - creditBalances[yieldFrom[_account]];
 194 |     |         }
 195 | *   |         return baseBalance;
 196 |     |     }
 197 |     | 
 198 |     |     /**
 199 |     |      * @notice Gets the credits balance of the specified address.
 200 |     |      * @dev Backwards compatible with old low res credits per token.
 201 |     |      * @param _account The address to query the balance of.
 202 |     |      * @return (uint256, uint256) Credit balance and credits per token of the
 203 |     |      *         address
 204 |     |      */
 205 |     |     function creditsBalanceOf(address _account)
 206 |     |         external
 207 |     |         view
 208 |     |         returns (uint256, uint256)
 209 |     |     {
 210 |     |         uint256 cpt = _creditsPerToken(_account);
 211 |     |         if (cpt == 1e27) {
 212 |     |             // For a period before the resolution upgrade, we created all new
 213 |     |             // contract accounts at high resolution. Since they are not changing
 214 |     |             // as a result of this upgrade, we will return their true values
 215 |     |             return (creditBalances[_account], cpt);
 216 |     |         } else {
 217 |     |             return (
 218 |     |                 creditBalances[_account] / RESOLUTION_INCREASE,
 219 |     |                 cpt / RESOLUTION_INCREASE
 220 |     |             );
 221 |     |         }
 222 |     |     }
 223 |     | 
 224 |     |     /**
 225 |     |      * @notice Gets the credits balance of the specified address.
 226 |     |      * @param _account The address to query the balance of.
 227 |     |      * @return (uint256, uint256, bool) Credit balance, credits per token of the
 228 |     |      *         address, and isUpgraded
 229 |     |      */
 230 | *   |     function creditsBalanceOfHighres(address _account)
 231 |     |         external
 232 |     |         view
 233 |     |         returns (
 234 | *   |             uint256,
 235 |     |             uint256,
 236 |     |             bool
 237 |     |         )
 238 |     |     {
 239 | *   |         return (
 240 | *   |             creditBalances[_account],
 241 | *   |             _creditsPerToken(_account),
 242 | *   |             true // all accounts have their resolution "upgraded"
 243 |     |         );
 244 |     |     }
 245 |     | 
 246 |     |     // Backwards compatible view
 247 |     |     function nonRebasingCreditsPerToken(address _account)
 248 |     |         external
 249 |     |         view
 250 |     |         returns (uint256)
 251 |     |     {
 252 |     |         return alternativeCreditsPerToken[_account];
 253 |     |     }
 254 |     | 
 255 |     |     /**
 256 |     |      * @notice Transfer tokens to a specified address.
 257 |     |      * @param _to the address to transfer to.
 258 |     |      * @param _value the amount to be transferred.
 259 |     |      * @return true on success.
 260 |     |      */
 261 | *   |     function transfer(address _to, uint256 _value) external returns (bool) {
 262 | *   |         require(_to != address(0), "Transfer to zero address");
 263 |     | 
 264 | *   |         _executeTransfer(msg.sender, _to, _value);
 265 |     | 
 266 | *   |         emit Transfer(msg.sender, _to, _value);
 267 |     |         return true;
 268 |     |     }
 269 |     | 
 270 |     |     /**
 271 |     |      * @notice Transfer tokens from one address to another.
 272 |     |      * @param _from The address you want to send tokens from.
 273 |     |      * @param _to The address you want to transfer to.
 274 |     |      * @param _value The amount of tokens to be transferred.
 275 |     |      * @return true on success.
 276 |     |      */
 277 | *   |     function transferFrom(
 278 |     |         address _from,
 279 |     |         address _to,
 280 |     |         uint256 _value
 281 | *   |     ) external returns (bool) {
 282 | *   |         require(_to != address(0), "Transfer to zero address");
 283 | *   |         uint256 userAllowance = allowances[_from][msg.sender];
 284 | *   |         require(_value <= userAllowance, "Allowance exceeded");
 285 |     | 
 286 |     |         unchecked {
 287 | *   |             allowances[_from][msg.sender] = userAllowance - _value;
 288 |     |         }
 289 |     | 
 290 | *   |         _executeTransfer(_from, _to, _value);
 291 |     | 
 292 | *   |         emit Transfer(_from, _to, _value);
 293 | *   |         return true;
 294 |     |     }
 295 |     | 
 296 | *   |     function _executeTransfer(
 297 |     |         address _from,
 298 |     |         address _to,
 299 |     |         uint256 _value
 300 | *   |     ) internal {
 301 | *   |         (
 302 | *   |             int256 fromRebasingCreditsDiff,
 303 | *   |             int256 fromNonRebasingSupplyDiff
 304 | *   |         ) = _adjustAccount(_from, -_value.toInt256());
 305 | *   |         (
 306 | *   |             int256 toRebasingCreditsDiff,
 307 | *   |             int256 toNonRebasingSupplyDiff
 308 | *   |         ) = _adjustAccount(_to, _value.toInt256());
 309 |     | 
 310 | *   |         _adjustGlobals(
 311 | *   |             fromRebasingCreditsDiff + toRebasingCreditsDiff,
 312 | *   |             fromNonRebasingSupplyDiff + toNonRebasingSupplyDiff
 313 |     |         );
 314 |     |     }
 315 |     | 
 316 | *   |     function _adjustAccount(address _account, int256 _balanceChange)
 317 |     |         internal
 318 | *   |         returns (int256 rebasingCreditsDiff, int256 nonRebasingSupplyDiff)
 319 | *   |     {
 320 | *   |         RebaseOptions state = rebaseState[_account];
 321 | *   |         int256 currentBalance = balanceOf(_account).toInt256();
 322 | *   |         if (currentBalance + _balanceChange < 0) {
 323 | *   |             revert("Transfer amount exceeds balance");
 324 |     |         }
 325 | *   |         uint256 newBalance = (currentBalance + _balanceChange).toUint256();
 326 |     | 
 327 | *   |         if (state == RebaseOptions.YieldDelegationSource) {
 328 |     |             address target = yieldTo[_account];
 329 |     |             uint256 targetOldBalance = balanceOf(target);
 330 |     |             uint256 targetNewCredits = _balanceToRebasingCredits(
 331 |     |                 targetOldBalance + newBalance
 332 |     |             );
 333 |     |             rebasingCreditsDiff =
 334 |     |                 targetNewCredits.toInt256() -
 335 |     |                 creditBalances[target].toInt256();
 336 |     | 
 337 |     |             creditBalances[_account] = newBalance;
 338 |     |             creditBalances[target] = targetNewCredits;
 339 | *   |         } else if (state == RebaseOptions.YieldDelegationTarget) {
 340 |     |             uint256 newCredits = _balanceToRebasingCredits(
 341 |     |                 newBalance + creditBalances[yieldFrom[_account]]
 342 |     |             );
 343 |     |             rebasingCreditsDiff =
 344 |     |                 newCredits.toInt256() -
 345 |     |                 creditBalances[_account].toInt256();
 346 |     |             creditBalances[_account] = newCredits;
 347 | *   |         } else {
 348 | *   |             _autoMigrate(_account);
 349 | *   |             uint256 alternativeCreditsPerTokenMem = alternativeCreditsPerToken[
 350 |     |                 _account
 351 |     |             ];
 352 | *   |             if (alternativeCreditsPerTokenMem > 0) {
 353 | *   |                 nonRebasingSupplyDiff = _balanceChange;
 354 | *   |                 if (alternativeCreditsPerTokenMem != 1e18) {
 355 |     |                     alternativeCreditsPerToken[_account] = 1e18;
 356 |     |                 }
 357 | *   |                 creditBalances[_account] = newBalance;
 358 |     |             } else {
 359 | *   |                 uint256 newCredits = _balanceToRebasingCredits(newBalance);
 360 | *   |                 rebasingCreditsDiff =
 361 | *   |                     newCredits.toInt256() -
 362 | *   |                     creditBalances[_account].toInt256();
 363 | *   |                 creditBalances[_account] = newCredits;
 364 |     |             }
 365 |     |         }
 366 |     |     }
 367 |     | 
 368 | *   |     function _adjustGlobals(
 369 |     |         int256 _rebasingCreditsDiff,
 370 |     |         int256 _nonRebasingSupplyDiff
 371 |     |     ) internal {
 372 | *   |         if (_rebasingCreditsDiff != 0) {
 373 | *   |             rebasingCredits_ = (rebasingCredits_.toInt256() +
 374 | *   |                 _rebasingCreditsDiff).toUint256();
 375 |     |         }
 376 | *   |         if (_nonRebasingSupplyDiff != 0) {
 377 | *   |             nonRebasingSupply = (nonRebasingSupply.toInt256() +
 378 | *   |                 _nonRebasingSupplyDiff).toUint256();
 379 |     |         }
 380 |     |     }
 381 |     | 
 382 |     |     /**
 383 |     |      * @notice Function to check the amount of tokens that _owner has allowed
 384 |     |      *      to `_spender`.
 385 |     |      * @param _owner The address which owns the funds.
 386 |     |      * @param _spender The address which will spend the funds.
 387 |     |      * @return The number of tokens still available for the _spender.
 388 |     |      */
 389 | *   |     function allowance(address _owner, address _spender)
 390 |     |         external
 391 |     |         view
 392 | *   |         returns (uint256)
 393 |     |     {
 394 | *   |         return allowances[_owner][_spender];
 395 |     |     }
 396 |     | 
 397 |     |     /**
 398 |     |      * @notice Approve the passed address to spend the specified amount of
 399 |     |      *      tokens on behalf of msg.sender.
 400 |     |      * @param _spender The address which will spend the funds.
 401 |     |      * @param _value The amount of tokens to be spent.
 402 |     |      * @return true on success.
 403 |     |      */
 404 | *   |     function approve(address _spender, uint256 _value) external returns (bool) {
 405 | *   |         allowances[msg.sender][_spender] = _value;
 406 | *   |         emit Approval(msg.sender, _spender, _value);
 407 | *   |         return true;
 408 |     |     }
 409 |     | 
 410 |     |     /**
 411 |     |      * @notice Creates `_amount` tokens and assigns them to `_account`,
 412 |     |      *     increasing the total supply.
 413 |     |      */
 414 | *   |     function mint(address _account, uint256 _amount) external onlyVault {
 415 | *   |         require(_account != address(0), "Mint to the zero address");
 416 |     | 
 417 |     |         // Account
 418 | *   |         (
 419 | *   |             int256 toRebasingCreditsDiff,
 420 | *   |             int256 toNonRebasingSupplyDiff
 421 | *   |         ) = _adjustAccount(_account, _amount.toInt256());
 422 |     |         // Globals
 423 | *   |         _adjustGlobals(toRebasingCreditsDiff, toNonRebasingSupplyDiff);
 424 | *   |         totalSupply = totalSupply + _amount;
 425 |     | 
 426 | *   |         require(totalSupply < MAX_SUPPLY, "Max supply");
 427 | *   |         emit Transfer(address(0), _account, _amount);
 428 |     |     }
 429 |     | 
 430 |     |     /**
 431 |     |      * @notice Destroys `_amount` tokens from `_account`,
 432 |     |      *     reducing the total supply.
 433 |     |      */
 434 | *   |     function burn(address _account, uint256 _amount) external onlyVault {
 435 | *   |         require(_account != address(0), "Burn from the zero address");
 436 | *   |         if (_amount == 0) {
 437 | *   |             return;
 438 |     |         }
 439 |     | 
 440 |     |         // Account
 441 | *   |         (
 442 | *   |             int256 toRebasingCreditsDiff,
 443 | *   |             int256 toNonRebasingSupplyDiff
 444 | *   |         ) = _adjustAccount(_account, -_amount.toInt256());
 445 |     |         // Globals
 446 | *   |         _adjustGlobals(toRebasingCreditsDiff, toNonRebasingSupplyDiff);
 447 | *   |         totalSupply = totalSupply - _amount;
 448 |     | 
 449 | *   |         emit Transfer(_account, address(0), _amount);
 450 |     |     }
 451 |     | 
 452 |     |     /**
 453 |     |      * @dev Get the credits per token for an account. Returns a fixed amount
 454 |     |      *      if the account is non-rebasing.
 455 |     |      * @param _account Address of the account.
 456 |     |      */
 457 | *   |     function _creditsPerToken(address _account)
 458 |     |         internal
 459 |     |         view
 460 | *   |         returns (uint256)
 461 |     |     {
 462 | *   |         uint256 alternativeCreditsPerTokenMem = alternativeCreditsPerToken[
 463 |     |             _account
 464 |     |         ];
 465 | *   |         if (alternativeCreditsPerTokenMem != 0) {
 466 | *   |             return alternativeCreditsPerTokenMem;
 467 |     |         } else {
 468 | *   |             return rebasingCreditsPerToken_;
 469 |     |         }
 470 |     |     }
 471 |     | 
 472 |     |     /**
 473 |     |      * @dev Auto migrate contracts to be non rebasing,
 474 |     |      *     unless they have opted into yield.
 475 |     |      * @param _account Address of the account.
 476 |     |      */
 477 | *   |     function _autoMigrate(address _account) internal {
 478 | *   |         uint256 codeLen = _account.code.length;
 479 | *   |         bool isEOA = (codeLen == 0) ||
 480 | *   |             (codeLen == 23 && bytes3(_account.code) == 0xef0100);
 481 |     |         // In previous code versions, contracts would not have had their
 482 |     |         // rebaseState[_account] set to RebaseOptions.NonRebasing when migrated
 483 |     |         // therefore we check the actual accounting used on the account as well.
 484 | *   |         if (
 485 | *   |             (!isEOA) &&
 486 | *   |             rebaseState[_account] == RebaseOptions.NotSet &&
 487 | *   |             alternativeCreditsPerToken[_account] == 0
 488 |     |         ) {
 489 | *   |             _rebaseOptOut(_account);
 490 |     |         }
 491 |     |     }
 492 |     | 
 493 |     |     /**
 494 |     |      * @dev Calculates credits from contract's global rebasingCreditsPerToken_, and
 495 |     |      *      also balance that corresponds to those credits. The latter is important
 496 |     |      *      when adjusting the contract's global nonRebasingSupply to circumvent any
 497 |     |      *      possible rounding errors.
 498 |     |      *
 499 |     |      * @param _balance Balance of the account.
 500 |     |      */
 501 | *   |     function _balanceToRebasingCredits(uint256 _balance)
 502 |     |         internal
 503 |     |         view
 504 | *   |         returns (uint256 rebasingCredits)
 505 |     |     {
 506 |     |         // Rounds up, because we need to ensure that accounts always have
 507 |     |         // at least the balance that they should have.
 508 |     |         // Note this should always be used on an absolute account value,
 509 |     |         // not on a possibly negative diff, because then the rounding would be wrong.
 510 | *   |         return ((_balance) * rebasingCreditsPerToken_ + 1e18 - 1) / 1e18;
 511 |     |     }
 512 |     | 
 513 |     |     /**
 514 |     |      * @notice The calling account will start receiving yield after a successful call.
 515 |     |      * @param _account Address of the account.
 516 |     |      */
 517 |     |     function governanceRebaseOptIn(address _account) external onlyGovernor {
 518 |     |         require(_account != address(0), "Zero address not allowed");
 519 |     |         _rebaseOptIn(_account);
 520 |     |     }
 521 |     | 
 522 |     |     /**
 523 |     |      * @notice The calling account will start receiving yield after a successful call.
 524 |     |      */
 525 | *   |     function rebaseOptIn() external {
 526 | *   |         _rebaseOptIn(msg.sender);
 527 |     |     }
 528 |     | 
 529 | *   |     function _rebaseOptIn(address _account) internal {
 530 | *   |         uint256 balance = balanceOf(_account);
 531 |     | 
 532 |     |         // prettier-ignore
 533 | *   |         require(
 534 | *   |             alternativeCreditsPerToken[_account] > 0 ||
 535 |     |                 // Accounts may explicitly `rebaseOptIn` regardless of
 536 |     |                 // accounting if they have a 0 balance.
 537 | *   |                 creditBalances[_account] == 0
 538 |     |             ,
 539 |     |             "Account must be non-rebasing"
 540 |     |         );
 541 | *   |         RebaseOptions state = rebaseState[_account];
 542 |     |         // prettier-ignore
 543 | *   |         require(
 544 | *   |             state == RebaseOptions.StdNonRebasing ||
 545 | *   |                 state == RebaseOptions.NotSet,
 546 |     |             "Only standard non-rebasing accounts can opt in"
 547 |     |         );
 548 |     | 
 549 | *   |         uint256 newCredits = _balanceToRebasingCredits(balance);
 550 |     | 
 551 |     |         // Account
 552 | *   |         rebaseState[_account] = RebaseOptions.StdRebasing;
 553 | *   |         alternativeCreditsPerToken[_account] = 0;
 554 | *   |         creditBalances[_account] = newCredits;
 555 |     |         // Globals
 556 | *   |         _adjustGlobals(newCredits.toInt256(), -balance.toInt256());
 557 |     | 
 558 | *   |         emit AccountRebasingEnabled(_account);
 559 |     |     }
 560 |     | 
 561 |     |     /**
 562 |     |      * @notice The calling account will no longer receive yield
 563 |     |      */
 564 | *   |     function rebaseOptOut() external {
 565 | *   |         _rebaseOptOut(msg.sender);
 566 |     |     }
 567 |     | 
 568 | *   |     function _rebaseOptOut(address _account) internal {
 569 | *   |         require(
 570 | *   |             alternativeCreditsPerToken[_account] == 0,
 571 |     |             "Account must be rebasing"
 572 |     |         );
 573 | *   |         RebaseOptions state = rebaseState[_account];
 574 | *   |         require(
 575 | *   |             state == RebaseOptions.StdRebasing || state == RebaseOptions.NotSet,
 576 |     |             "Only standard rebasing accounts can opt out"
 577 |     |         );
 578 |     | 
 579 | *   |         uint256 oldCredits = creditBalances[_account];
 580 | *   |         uint256 balance = balanceOf(_account);
 581 |     | 
 582 |     |         // Account
 583 | *   |         rebaseState[_account] = RebaseOptions.StdNonRebasing;
 584 | *   |         alternativeCreditsPerToken[_account] = 1e18;
 585 | *   |         creditBalances[_account] = balance;
 586 |     |         // Globals
 587 | *   |         _adjustGlobals(-oldCredits.toInt256(), balance.toInt256());
 588 |     | 
 589 | *   |         emit AccountRebasingDisabled(_account);
 590 |     |     }
 591 |     | 
 592 |     |     /**
 593 |     |      * @notice Distribute yield to users. This changes the exchange rate
 594 |     |      *  between "credits" and OUSD tokens to change rebasing user's balances.
 595 |     |      * @param _newTotalSupply New total supply of OUSD.
 596 |     |      */
 597 | *   |     function changeSupply(uint256 _newTotalSupply) external onlyVault {
 598 | *   |         require(totalSupply > 0, "Cannot increase 0 supply");
 599 |     | 
 600 | *   |         if (totalSupply == _newTotalSupply) {
 601 | *   |             emit TotalSupplyUpdatedHighres(
 602 | *   |                 totalSupply,
 603 | *   |                 rebasingCredits_,
 604 | *   |                 rebasingCreditsPerToken_
 605 |     |             );
 606 |     |             return;
 607 |     |         }
 608 |     | 
 609 | *   |         totalSupply = _newTotalSupply > MAX_SUPPLY
 610 |     |             ? MAX_SUPPLY
 611 | *   |             : _newTotalSupply;
 612 |     | 
 613 | *   |         uint256 rebasingSupply = totalSupply - nonRebasingSupply;
 614 |     |         // round up in the favour of the protocol
 615 | *   |         rebasingCreditsPerToken_ =
 616 | *   |             (rebasingCredits_ * 1e18 + rebasingSupply - 1) /
 617 | *   |             rebasingSupply;
 618 |     | 
 619 | *   |         require(rebasingCreditsPerToken_ > 0, "Invalid change in supply");
 620 |     | 
 621 | *   |         emit TotalSupplyUpdatedHighres(
 622 | *   |             totalSupply,
 623 | *   |             rebasingCredits_,
 624 | *   |             rebasingCreditsPerToken_
 625 |     |         );
 626 |     |     }
 627 |     | 
 628 |     |     /*
 629 |     |      * @notice Send the yield from one account to another account.
 630 |     |      *         Each account keeps its own balances.
 631 |     |      */
 632 |     |     function delegateYield(address _from, address _to)
 633 |     |         external
 634 |     |         onlyGovernorOrStrategist
 635 |     |     {
 636 |     |         require(_from != address(0), "Zero from address not allowed");
 637 |     |         require(_to != address(0), "Zero to address not allowed");
 638 |     | 
 639 |     |         require(_from != _to, "Cannot delegate to self");
 640 |     |         require(
 641 |     |             yieldFrom[_to] == address(0) &&
 642 |     |                 yieldTo[_to] == address(0) &&
 643 |     |                 yieldFrom[_from] == address(0) &&
 644 |     |                 yieldTo[_from] == address(0),
 645 |     |             "Blocked by existing yield delegation"
 646 |     |         );
 647 |     |         RebaseOptions stateFrom = rebaseState[_from];
 648 |     |         RebaseOptions stateTo = rebaseState[_to];
 649 |     | 
 650 |     |         require(
 651 |     |             stateFrom == RebaseOptions.NotSet ||
 652 |     |                 stateFrom == RebaseOptions.StdNonRebasing ||
 653 |     |                 stateFrom == RebaseOptions.StdRebasing,
 654 |     |             "Invalid rebaseState from"
 655 |     |         );
 656 |     | 
 657 |     |         require(
 658 |     |             stateTo == RebaseOptions.NotSet ||
 659 |     |                 stateTo == RebaseOptions.StdNonRebasing ||
 660 |     |                 stateTo == RebaseOptions.StdRebasing,
 661 |     |             "Invalid rebaseState to"
 662 |     |         );
 663 |     | 
 664 |     |         if (alternativeCreditsPerToken[_from] == 0) {
 665 |     |             _rebaseOptOut(_from);
 666 |     |         }
 667 |     |         if (alternativeCreditsPerToken[_to] > 0) {
 668 |     |             _rebaseOptIn(_to);
 669 |     |         }
 670 |     | 
 671 |     |         uint256 fromBalance = balanceOf(_from);
 672 |     |         uint256 toBalance = balanceOf(_to);
 673 |     |         uint256 oldToCredits = creditBalances[_to];
 674 |     |         uint256 newToCredits = _balanceToRebasingCredits(
 675 |     |             fromBalance + toBalance
 676 |     |         );
 677 |     | 
 678 |     |         // Set up the bidirectional links
 679 |     |         yieldTo[_from] = _to;
 680 |     |         yieldFrom[_to] = _from;
 681 |     | 
 682 |     |         // Local
 683 |     |         rebaseState[_from] = RebaseOptions.YieldDelegationSource;
 684 |     |         alternativeCreditsPerToken[_from] = 1e18;
 685 |     |         creditBalances[_from] = fromBalance;
 686 |     |         rebaseState[_to] = RebaseOptions.YieldDelegationTarget;
 687 |     |         creditBalances[_to] = newToCredits;
 688 |     | 
 689 |     |         // Global
 690 |     |         int256 creditsChange = newToCredits.toInt256() -
 691 |     |             oldToCredits.toInt256();
 692 | *   |         _adjustGlobals(creditsChange, -(fromBalance).toInt256());
 693 |     |         emit YieldDelegated(_from, _to);
 694 |     |     }
 695 |     | 
 696 |     |     /*
 697 |     |      * @notice Stop sending the yield from one account to another account.
 698 |     |      */
 699 | *   |     function undelegateYield(address _from) external onlyGovernorOrStrategist {
 700 |     |         // Require a delegation, which will also ensure a valid delegation
 701 |     |         require(yieldTo[_from] != address(0), "Zero address not allowed");
 702 |     | 
 703 |     |         address to = yieldTo[_from];
 704 |     |         uint256 fromBalance = balanceOf(_from);
 705 |     |         uint256 toBalance = balanceOf(to);
 706 |     |         uint256 oldToCredits = creditBalances[to];
 707 |     |         uint256 newToCredits = _balanceToRebasingCredits(toBalance);
 708 |     | 
 709 |     |         // Remove the bidirectional links
 710 |     |         yieldFrom[to] = address(0);
 711 |     |         yieldTo[_from] = address(0);
 712 |     | 
 713 |     |         // Local
 714 |     |         rebaseState[_from] = RebaseOptions.StdNonRebasing;
 715 |     |         // alternativeCreditsPerToken[from] already 1e18 from `delegateYield()`
 716 |     |         creditBalances[_from] = fromBalance;
 717 |     |         rebaseState[to] = RebaseOptions.StdRebasing;
 718 |     |         // alternativeCreditsPerToken[to] already 0 from `delegateYield()`
 719 |     |         creditBalances[to] = newToCredits;
 720 |     | 
 721 |     |         // Global
 722 |     |         int256 creditsChange = newToCredits.toInt256() -
 723 |     |             oldToCredits.toInt256();
 724 | *   |         _adjustGlobals(creditsChange, fromBalance.toInt256());
 725 |     |         emit YieldUndelegated(_from, to);
 726 |     |     }
 727 |     | }
 728 |     | 

/opt/scfuzzbench/work/target/contracts/contracts/utils/Helpers.sol
  1 |     | // SPDX-License-Identifier: BUSL-1.1
  2 |     | pragma solidity ^0.8.0;
  3 |     | 
  4 |     | import { IBasicToken } from "../interfaces/IBasicToken.sol";
  5 |     | 
  6 |     | library Helpers {
  7 |     |     /**
  8 |     |      * @notice Fetch the `symbol()` from an ERC20 token
  9 |     |      * @dev Grabs the `symbol()` from a contract
 10 |     |      * @param _token Address of the ERC20 token
 11 |     |      * @return string Symbol of the ERC20 token
 12 |     |      */
 13 |     |     function getSymbol(address _token) internal view returns (string memory) {
 14 |     |         string memory symbol = IBasicToken(_token).symbol();
 15 |     |         return symbol;
 16 |     |     }
 17 |     | 
 18 |     |     /**
 19 |     |      * @notice Fetch the `decimals()` from an ERC20 token
 20 |     |      * @dev Grabs the `decimals()` from a contract and fails if
 21 |     |      *      the decimal value does not live within a certain range
 22 |     |      * @param _token Address of the ERC20 token
 23 |     |      * @return uint256 Decimals of the ERC20 token
 24 |     |      */
 25 |     |     function getDecimals(address _token) internal view returns (uint256) {
 26 |     |         uint256 decimals = IBasicToken(_token).decimals();
 27 |     |         require(
 28 |     |             decimals >= 4 && decimals <= 18,
 29 |     |             "Token must have sufficient decimal places"
 30 |     |         );
 31 |     | 
 32 |     |         return decimals;
 33 |     |     }
 34 |     | }
 35 |     | 

/opt/scfuzzbench/work/target/contracts/contracts/utils/Initializable.sol
  1 |     | // SPDX-License-Identifier: BUSL-1.1
  2 |     | pragma solidity ^0.8.0;
  3 |     | 
  4 |     | /**
  5 |     |  * @title Base contract any contracts that need to initialize state after deployment.
  6 |     |  * @author Origin Protocol Inc
  7 |     |  */
  8 |     | abstract contract Initializable {
  9 |     |     /**
 10 |     |      * @dev Indicates that the contract has been initialized.
 11 |     |      */
 12 |     |     bool private initialized;
 13 |     | 
 14 |     |     /**
 15 |     |      * @dev Indicates that the contract is in the process of being initialized.
 16 |     |      */
 17 |     |     bool private initializing;
 18 |     | 
 19 |     |     /**
 20 |     |      * @dev Modifier to protect an initializer function from being invoked twice.
 21 |     |      */
 22 |     |     modifier initializer() {
 23 |     |         require(
 24 |     |             initializing || !initialized,
 25 |     |             "Initializable: contract is already initialized"
 26 |     |         );
 27 |     | 
 28 |     |         bool isTopLevelCall = !initializing;
 29 |     |         if (isTopLevelCall) {
 30 |     |             initializing = true;
 31 |     |             initialized = true;
 32 |     |         }
 33 |     | 
 34 |     |         _;
 35 |     | 
 36 |     |         if (isTopLevelCall) {
 37 |     |             initializing = false;
 38 |     |         }
 39 |     |     }
 40 |     | 
 41 |     |     uint256[50] private ______gap;
 42 |     | }
 43 |     | 

/opt/scfuzzbench/work/target/contracts/contracts/utils/StableMath.sol
   1 |     | // SPDX-License-Identifier: BUSL-1.1
   2 |     | pragma solidity ^0.8.0;
   3 |     | 
   4 |     | import { SafeMath } from "@openzeppelin/contracts/utils/math/SafeMath.sol";
   5 |     | 
   6 |     | // Based on StableMath from Stability Labs Pty. Ltd.
   7 |     | // https://github.com/mstable/mStable-contracts/blob/master/contracts/shared/StableMath.sol
   8 |     | 
   9 |     | library StableMath {
  10 |     |     using SafeMath for uint256;
  11 |     | 
  12 |     |     /**
  13 |     |      * @dev Scaling unit for use in specific calculations,
  14 |     |      * where 1 * 10**18, or 1e18 represents a unit '1'
  15 |     |      */
  16 | *   |     uint256 private constant FULL_SCALE = 1e18;
  17 |     | 
  18 |     |     /***************************************
  19 |     |                     Helpers
  20 |     |     ****************************************/
  21 |     | 
  22 |     |     /**
  23 |     |      * @dev Adjust the scale of an integer
  24 |     |      * @param to Decimals to scale to
  25 |     |      * @param from Decimals to scale from
  26 |     |      */
  27 |     |     function scaleBy(
  28 |     |         uint256 x,
  29 |     |         uint256 to,
  30 |     |         uint256 from
  31 |     |     ) internal pure returns (uint256) {
  32 |     |         if (to > from) {
  33 |     |             x = x.mul(10**(to - from));
  34 |     |         } else if (to < from) {
  35 |     |             // slither-disable-next-line divide-before-multiply
  36 |     |             x = x.div(10**(from - to));
  37 |     |         }
  38 |     |         return x;
  39 |     |     }
  40 |     | 
  41 |     |     /***************************************
  42 |     |                Precise Arithmetic
  43 |     |     ****************************************/
  44 |     | 
  45 |     |     /**
  46 |     |      * @dev Multiplies two precise units, and then truncates by the full scale
  47 |     |      * @param x Left hand input to multiplication
  48 |     |      * @param y Right hand input to multiplication
  49 |     |      * @return Result after multiplying the two inputs and then dividing by the shared
  50 |     |      *         scale unit
  51 |     |      */
  52 |     |     function mulTruncate(uint256 x, uint256 y) internal pure returns (uint256) {
  53 |     |         return mulTruncateScale(x, y, FULL_SCALE);
  54 |     |     }
  55 |     | 
  56 |     |     /**
  57 |     |      * @dev Multiplies two precise units, and then truncates by the given scale. For example,
  58 |     |      * when calculating 90% of 10e18, (10e18 * 9e17) / 1e18 = (9e36) / 1e18 = 9e18
  59 |     |      * @param x Left hand input to multiplication
  60 |     |      * @param y Right hand input to multiplication
  61 |     |      * @param scale Scale unit
  62 |     |      * @return Result after multiplying the two inputs and then dividing by the shared
  63 |     |      *         scale unit
  64 |     |      */
  65 |     |     function mulTruncateScale(
  66 |     |         uint256 x,
  67 |     |         uint256 y,
  68 |     |         uint256 scale
  69 |     |     ) internal pure returns (uint256) {
  70 |     |         // e.g. assume scale = fullScale
  71 |     |         // z = 10e18 * 9e17 = 9e36
  72 |     |         uint256 z = x.mul(y);
  73 |     |         // return 9e36 / 1e18 = 9e18
  74 |     |         return z.div(scale);
  75 |     |     }
  76 |     | 
  77 |     |     /**
  78 |     |      * @dev Multiplies two precise units, and then truncates by the full scale, rounding up the result
  79 |     |      * @param x Left hand input to multiplication
  80 |     |      * @param y Right hand input to multiplication
  81 |     |      * @return Result after multiplying the two inputs and then dividing by the shared
  82 |     |      *          scale unit, rounded up to the closest base unit.
  83 |     |      */
  84 |     |     function mulTruncateCeil(uint256 x, uint256 y)
  85 |     |         internal
  86 |     |         pure
  87 |     |         returns (uint256)
  88 |     |     {
  89 |     |         // e.g. 8e17 * 17268172638 = 138145381104e17
  90 |     |         uint256 scaled = x.mul(y);
  91 |     |         // e.g. 138145381104e17 + 9.99...e17 = 138145381113.99...e17
  92 |     |         uint256 ceil = scaled.add(FULL_SCALE.sub(1));
  93 |     |         // e.g. 13814538111.399...e18 / 1e18 = 13814538111
  94 |     |         return ceil.div(FULL_SCALE);
  95 |     |     }
  96 |     | 
  97 |     |     /**
  98 |     |      * @dev Precisely divides two units, by first scaling the left hand operand. Useful
  99 |     |      *      for finding percentage weightings, i.e. 8e18/10e18 = 80% (or 8e17)
 100 |     |      * @param x Left hand input to division
 101 |     |      * @param y Right hand input to division
 102 |     |      * @return Result after multiplying the left operand by the scale, and
 103 |     |      *         executing the division on the right hand input.
 104 |     |      */
 105 | *   |     function divPrecisely(uint256 x, uint256 y)
 106 |     |         internal
 107 |     |         pure
 108 | *   |         returns (uint256)
 109 |     |     {
 110 |     |         // e.g. 8e18 * 1e18 = 8e36
 111 | *   |         uint256 z = x.mul(FULL_SCALE);
 112 |     |         // e.g. 8e36 / 10e18 = 8e17
 113 | *   |         return z.div(y);
 114 |     |     }
 115 |     | }
 116 |     | 

/opt/scfuzzbench/work/target/contracts/contracts/vault/VaultStorage.sol
   1 |     | // SPDX-License-Identifier: BUSL-1.1
   2 |     | pragma solidity ^0.8.0;
   3 |     | 
   4 |     | /**
   5 |     |  * @title OToken VaultStorage contract
   6 |     |  * @notice The VaultStorage contract defines the storage for the Vault contracts
   7 |     |  * @author Origin Protocol Inc
   8 |     |  */
   9 |     | 
  10 |     | import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
  11 |     | import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
  12 |     | import { Address } from "@openzeppelin/contracts/utils/Address.sol";
  13 |     | 
  14 |     | import { IStrategy } from "../interfaces/IStrategy.sol";
  15 |     | import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
  16 |     | import { Governable } from "../governance/Governable.sol";
  17 |     | import { OUSD } from "../token/OUSD.sol";
  18 |     | import { Initializable } from "../utils/Initializable.sol";
  19 |     | import "../utils/Helpers.sol";
  20 |     | 
  21 |     | abstract contract VaultStorage is Initializable, Governable {
  22 |     |     using SafeERC20 for IERC20;
  23 |     | 
  24 |     |     event AssetAllocated(address _asset, address _strategy, uint256 _amount);
  25 |     |     event StrategyApproved(address _addr);
  26 |     |     event StrategyRemoved(address _addr);
  27 |     |     event Mint(address _addr, uint256 _value);
  28 |     |     event Redeem(address _addr, uint256 _value);
  29 |     |     event CapitalPaused();
  30 |     |     event CapitalUnpaused();
  31 |     |     event DefaultStrategyUpdated(address _strategy);
  32 |     |     event RebasePaused();
  33 |     |     event RebaseUnpaused();
  34 |     |     event VaultBufferUpdated(uint256 _vaultBuffer);
  35 |     |     event AllocateThresholdUpdated(uint256 _threshold);
  36 |     |     event StrategistUpdated(address _address);
  37 |     |     event MaxSupplyDiffChanged(uint256 maxSupplyDiff);
  38 |     |     event YieldDistribution(address _to, uint256 _yield, uint256 _fee);
  39 |     |     event TrusteeFeeBpsChanged(uint256 _basis);
  40 |     |     event TrusteeAddressChanged(address _address);
  41 |     |     event StrategyAddedToMintWhitelist(address indexed strategy);
  42 |     |     event StrategyRemovedFromMintWhitelist(address indexed strategy);
  43 |     |     event RebasePerSecondMaxChanged(uint256 rebaseRatePerSecond);
  44 |     |     event DripDurationChanged(uint256 dripDuration);
  45 |     |     event OperatorUpdated(address newOperator);
  46 |     |     event WithdrawalRequested(
  47 |     |         address indexed _withdrawer,
  48 |     |         uint256 indexed _requestId,
  49 |     |         uint256 _amount,
  50 |     |         uint256 _queued
  51 |     |     );
  52 |     |     event WithdrawalClaimed(
  53 |     |         address indexed _withdrawer,
  54 |     |         uint256 indexed _requestId,
  55 |     |         uint256 _amount
  56 |     |     );
  57 |     |     event WithdrawalClaimable(uint256 _claimable, uint256 _newClaimable);
  58 |     |     event WithdrawalClaimDelayUpdated(uint256 _newDelay);
  59 |     | 
  60 |     |     // Since we are proxy, all state should be uninitalized.
  61 |     |     // Since this storage contract does not have logic directly on it
  62 |     |     // we should not be checking for to see if these variables can be constant.
  63 |     |     // slither-disable-start uninitialized-state
  64 |     |     // slither-disable-start constable-states
  65 |     | 
  66 |     |     /// @dev mapping of supported vault assets to their configuration
  67 |     |     uint256 private _deprecated_assets;
  68 |     |     /// @dev list of all assets supported by the vault.
  69 |     |     address[] private _deprecated_allAssets;
  70 |     | 
  71 |     |     // Strategies approved for use by the Vault
  72 |     |     struct Strategy {
  73 |     |         bool isSupported;
  74 |     |         uint256 _deprecated; // Deprecated storage slot
  75 |     |     }
  76 |     |     /// @dev mapping of strategy contracts to their configuration
  77 |     |     mapping(address => Strategy) public strategies;
  78 |     |     /// @dev list of all vault strategies
  79 |     |     address[] internal allStrategies;
  80 |     | 
  81 |     |     /// @notice Address of the Oracle price provider contract
  82 |     |     address private _deprecated_priceProvider;
  83 |     |     /// @notice pause rebasing if true
  84 |     |     bool public rebasePaused;
  85 |     |     /// @notice pause operations that change the OToken supply.
  86 |     |     /// eg mint, redeem, allocate, mint/burn for strategy
  87 |     |     bool public capitalPaused;
  88 |     |     /// @notice Redemption fee in basis points. eg 50 = 0.5%
  89 |     |     uint256 private _deprecated_redeemFeeBps;
  90 |     |     /// @notice Percentage of assets to keep in Vault to handle (most) withdrawals. 100% = 1e18.
  91 |     |     uint256 public vaultBuffer;
  92 |     |     /// @notice OToken mints over this amount automatically allocate funds. 18 decimals.
  93 |     |     uint256 public autoAllocateThreshold;
  94 |     |     /// @dev Deprecated. Was the auto-rebase trigger threshold for mint/redeem.
  95 |     |     ///      Storage slot retained for proxy compatibility; no longer read or written.
  96 |     |     uint256 internal __deprecatedRebaseThreshold;
  97 |     | 
  98 |     |     /// @dev Address of the OToken token. eg OUSD or OETH.
  99 |     |     OUSD public oToken;
 100 |     | 
 101 |     |     /// @dev Address of the contract responsible for post rebase syncs with AMMs
 102 |     |     address private _deprecated_rebaseHooksAddr = address(0);
 103 |     | 
 104 |     |     /// @dev Deprecated: Address of Uniswap
 105 |     |     address private _deprecated_uniswapAddr = address(0);
 106 |     | 
 107 |     |     /// @notice Address of the Strategist
 108 |     |     address public strategistAddr = address(0);
 109 |     | 
 110 |     |     /// @notice Mapping of asset address to the Strategy that they should automatically
 111 |     |     // be allocated to
 112 |     |     uint256 private _deprecated_assetDefaultStrategies;
 113 |     | 
 114 |     |     /// @notice Max difference between total supply and total value of assets. 18 decimals.
 115 |     |     uint256 public maxSupplyDiff;
 116 |     | 
 117 |     |     /// @notice Trustee contract that can collect a percentage of yield
 118 |     |     address public trusteeAddress;
 119 |     | 
 120 |     |     /// @notice Amount of yield collected in basis points. eg 2000 = 20%
 121 |     |     uint256 public trusteeFeeBps;
 122 |     | 
 123 |     |     /// @dev Deprecated: Tokens that should be swapped for stablecoins
 124 |     |     address[] private _deprecated_swapTokens;
 125 |     | 
 126 |     |     /// @notice Metapool strategy that is allowed to mint/burn OTokens without changing collateral
 127 |     | 
 128 |     |     address private _deprecated_ousdMetaStrategy;
 129 |     | 
 130 |     |     /// @notice How much OTokens are currently minted by the strategy
 131 |     |     int256 private _deprecated_netOusdMintedForStrategy;
 132 |     | 
 133 |     |     /// @notice How much net total OTokens are allowed to be minted by all strategies
 134 |     |     uint256 private _deprecated_netOusdMintForStrategyThreshold;
 135 |     | 
 136 |     |     uint256 private _deprecated_swapConfig;
 137 |     | 
 138 |     |     // List of strategies that can mint oTokens directly
 139 |     |     // Used in OETHBaseVaultCore
 140 |     |     mapping(address => bool) public isMintWhitelistedStrategy;
 141 |     | 
 142 |     |     /// @notice Address of the Dripper contract that streams harvested rewards to the Vault
 143 |     |     /// @dev The vault is proxied so needs to be set with setDripper against the proxy contract.
 144 |     |     address private _deprecated_dripper;
 145 |     | 
 146 |     |     /// Withdrawal Queue Storage /////
 147 |     | 
 148 |     |     struct WithdrawalQueueMetadata {
 149 |     |         // cumulative total of all withdrawal requests included the ones that have already been claimed
 150 |     |         uint128 queued;
 151 |     |         // cumulative total of all the requests that can be claimed including the ones that have already been claimed
 152 |     |         uint128 claimable;
 153 |     |         // total of all the requests that have been claimed
 154 |     |         uint128 claimed;
 155 |     |         // index of the next withdrawal request starting at 0
 156 |     |         uint128 nextWithdrawalIndex;
 157 |     |     }
 158 |     | 
 159 |     |     /// @notice Global metadata for the withdrawal queue including:
 160 |     |     /// queued - cumulative total of all withdrawal requests included the ones that have already been claimed
 161 |     |     /// claimable - cumulative total of all the requests that can be claimed including the ones already claimed
 162 |     |     /// claimed - total of all the requests that have been claimed
 163 |     |     /// nextWithdrawalIndex - index of the next withdrawal request starting at 0
 164 |     |     WithdrawalQueueMetadata public withdrawalQueueMetadata;
 165 |     | 
 166 |     |     struct WithdrawalRequest {
 167 |     |         address withdrawer;
 168 |     |         bool claimed;
 169 |     |         uint40 timestamp; // timestamp of the withdrawal request
 170 |     |         // Amount of oTokens to redeem. eg OETH
 171 |     |         uint128 amount;
 172 |     |         // cumulative total of all withdrawal requests including this one.
 173 |     |         // this request can be claimed when this queued amount is less than or equal to the queue's claimable amount.
 174 |     |         uint128 queued;
 175 |     |     }
 176 |     | 
 177 |     |     /// @notice Mapping of withdrawal request indices to the user withdrawal request data
 178 |     |     mapping(uint256 => WithdrawalRequest) public withdrawalRequests;
 179 |     | 
 180 |     |     /// @notice Sets a minimum delay that is required to elapse between
 181 |     |     ///     requesting async withdrawals and claiming the request.
 182 |     |     ///     When set to 0 async withdrawals are disabled.
 183 |     |     uint256 public withdrawalClaimDelay;
 184 |     | 
 185 |     |     /// @notice Time in seconds that the vault last rebased yield.
 186 |     |     uint64 public lastRebase;
 187 |     | 
 188 |     |     /// @notice Automatic rebase yield calculations. In seconds. Set to 0 or 1 to disable.
 189 |     |     uint64 public dripDuration;
 190 |     | 
 191 |     |     /// @notice max rebase percentage per second
 192 |     |     ///   Can be used to set maximum yield of the protocol,
 193 |     |     ///   spreading out yield over time
 194 |     |     uint64 public rebasePerSecondMax;
 195 |     | 
 196 |     |     /// @notice target rebase rate limit, based on past rates and funds available.
 197 |     |     uint64 public rebasePerSecondTarget;
 198 |     | 
 199 |     |     uint256 internal constant MAX_REBASE = 0.02 ether;
 200 |     |     uint256 internal constant MAX_REBASE_PER_SECOND =
 201 |     |         uint256(0.05 ether) / 1 days;
 202 |     | 
 203 |     |     /// @notice Default strategy for asset
 204 |     |     address public defaultStrategy;
 205 |     | 
 206 |     |     /// @notice Address authorized to call `rebase()` directly. The Governor
 207 |     |     ///         and Strategist are always allowed in addition to this address.
 208 |     |     address public operatorAddr;
 209 |     | 
 210 |     |     // For future use
 211 |     |     uint256[41] private __gap;
 212 |     | 
 213 |     |     /// @notice Index of WETH asset in allAssets array
 214 |     |     /// Legacy OETHVaultCore code, relocated here for vault consistency.
 215 |     |     uint256 private _deprecated_wethAssetIndex;
 216 |     | 
 217 |     |     /// @dev Address of the asset (eg. WETH or USDC)
 218 |     |     address public immutable asset;
 219 |     |     uint8 internal immutable assetDecimals;
 220 |     | 
 221 |     |     // slither-disable-end constable-states
 222 |     |     // slither-disable-end uninitialized-state
 223 |     | 
 224 |     |     constructor(address _asset) {
 225 |     |         uint8 _decimals = IERC20Metadata(_asset).decimals();
 226 |     |         require(_decimals <= 18, "invalid asset decimals");
 227 |     |         asset = _asset;
 228 |     |         assetDecimals = _decimals;
 229 |     |     }
 230 |     | 
 231 |     |     /// @notice Deprecated: use `oToken()` instead.
 232 |     |     function oUSD() external view returns (OUSD) {
 233 |     |         return oToken;
 234 |     |     }
 235 |     | }
 236 |     | 

/opt/scfuzzbench/work/target/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol
  1 |     | // SPDX-License-Identifier: MIT
  2 |     | // OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)
  3 |     | 
  4 |     | pragma solidity ^0.8.0;
  5 |     | 
  6 |     | /**
  7 |     |  * @dev Interface of the ERC20 standard as defined in the EIP.
  8 |     |  */
  9 |     | interface IERC20 {
 10 |     |     /**
 11 |     |      * @dev Returns the amount of tokens in existence.
 12 |     |      */
 13 |     |     function totalSupply() external view returns (uint256);
 14 |     | 
 15 |     |     /**
 16 |     |      * @dev Returns the amount of tokens owned by `account`.
 17 |     |      */
 18 |     |     function balanceOf(address account) external view returns (uint256);
 19 |     | 
 20 |     |     /**
 21 |     |      * @dev Moves `amount` tokens from the caller's account to `recipient`.
 22 |     |      *
 23 |     |      * Returns a boolean value indicating whether the operation succeeded.
 24 |     |      *
 25 |     |      * Emits a {Transfer} event.
 26 |     |      */
 27 |     |     function transfer(address recipient, uint256 amount) external returns (bool);
 28 |     | 
 29 |     |     /**
 30 |     |      * @dev Returns the remaining number of tokens that `spender` will be
 31 |     |      * allowed to spend on behalf of `owner` through {transferFrom}. This is
 32 |     |      * zero by default.
 33 |     |      *
 34 |     |      * This value changes when {approve} or {transferFrom} are called.
 35 |     |      */
 36 |     |     function allowance(address owner, address spender) external view returns (uint256);
 37 |     | 
 38 |     |     /**
 39 |     |      * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
 40 |     |      *
 41 |     |      * Returns a boolean value indicating whether the operation succeeded.
 42 |     |      *
 43 |     |      * IMPORTANT: Beware that changing an allowance with this method brings the risk
 44 |     |      * that someone may use both the old and the new allowance by unfortunate
 45 |     |      * transaction ordering. One possible solution to mitigate this race
 46 |     |      * condition is to first reduce the spender's allowance to 0 and set the
 47 |     |      * desired value afterwards:
 48 |     |      * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
 49 |     |      *
 50 |     |      * Emits an {Approval} event.
 51 |     |      */
 52 |     |     function approve(address spender, uint256 amount) external returns (bool);
 53 |     | 
 54 |     |     /**
 55 |     |      * @dev Moves `amount` tokens from `sender` to `recipient` using the
 56 |     |      * allowance mechanism. `amount` is then deducted from the caller's
 57 |     |      * allowance.
 58 |     |      *
 59 |     |      * Returns a boolean value indicating whether the operation succeeded.
 60 |     |      *
 61 |     |      * Emits a {Transfer} event.
 62 |     |      */
 63 |     |     function transferFrom(
 64 |     |         address sender,
 65 |     |         address recipient,
 66 |     |         uint256 amount
 67 |     |     ) external returns (bool);
 68 |     | 
 69 |     |     /**
 70 |     |      * @dev Emitted when `value` tokens are moved from one account (`from`) to
 71 |     |      * another (`to`).
 72 |     |      *
 73 |     |      * Note that `value` may be zero.
 74 |     |      */
 75 |     |     event Transfer(address indexed from, address indexed to, uint256 value);
 76 |     | 
 77 |     |     /**
 78 |     |      * @dev Emitted when the allowance of a `spender` for an `owner` is set by
 79 |     |      * a call to {approve}. `value` is the new allowance.
 80 |     |      */
 81 |     |     event Approval(address indexed owner, address indexed spender, uint256 value);
 82 |     | }
 83 |     | 

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

/opt/scfuzzbench/work/target/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol
   1 |     | // SPDX-License-Identifier: MIT
   2 |     | // OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)
   3 |     | 
   4 |     | pragma solidity ^0.8.0;
   5 |     | 
   6 |     | import "../IERC20.sol";
   7 |     | import "../../../utils/Address.sol";
   8 |     | 
   9 |     | /**
  10 |     |  * @title SafeERC20
  11 |     |  * @dev Wrappers around ERC20 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 |     |     using Address for address;
  20 |     | 
  21 |     |     function safeTransfer(
  22 |     |         IERC20 token,
  23 |     |         address to,
  24 |     |         uint256 value
  25 |     |     ) internal {
  26 |     |         _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
  27 |     |     }
  28 |     | 
  29 |     |     function safeTransferFrom(
  30 |     |         IERC20 token,
  31 |     |         address from,
  32 |     |         address to,
  33 |     |         uint256 value
  34 |     |     ) internal {
  35 |     |         _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
  36 |     |     }
  37 |     | 
  38 |     |     /**
  39 |     |      * @dev Deprecated. This function has issues similar to the ones found in
  40 |     |      * {IERC20-approve}, and its usage is discouraged.
  41 |     |      *
  42 |     |      * Whenever possible, use {safeIncreaseAllowance} and
  43 |     |      * {safeDecreaseAllowance} instead.
  44 |     |      */
  45 |     |     function safeApprove(
  46 |     |         IERC20 token,
  47 |     |         address spender,
  48 |     |         uint256 value
  49 |     |     ) internal {
  50 |     |         // safeApprove should only be called when setting an initial allowance,
  51 |     |         // or when resetting it to zero. To increase and decrease it, use
  52 |     |         // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
  53 |     |         require(
  54 |     |             (value == 0) || (token.allowance(address(this), spender) == 0),
  55 |     |             "SafeERC20: approve from non-zero to non-zero allowance"
  56 |     |         );
  57 |     |         _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
  58 |     |     }
  59 |     | 
  60 |     |     function safeIncreaseAllowance(
  61 |     |         IERC20 token,
  62 |     |         address spender,
  63 |     |         uint256 value
  64 |     |     ) internal {
  65 |     |         uint256 newAllowance = token.allowance(address(this), spender) + value;
  66 |     |         _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
  67 |     |     }
  68 |     | 
  69 |     |     function safeDecreaseAllowance(
  70 |     |         IERC20 token,
  71 |     |         address spender,
  72 |     |         uint256 value
  73 |     |     ) internal {
  74 |     |         unchecked {
  75 |     |             uint256 oldAllowance = token.allowance(address(this), spender);
  76 |     |             require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
  77 |     |             uint256 newAllowance = oldAllowance - value;
  78 |     |             _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
  79 |     |         }
  80 |     |     }
  81 |     | 
  82 |     |     /**
  83 |     |      * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
  84 |     |      * on the return value: the return value is optional (but if data is returned, it must not be false).
  85 |     |      * @param token The token targeted by the call.
  86 |     |      * @param data The call data (encoded using abi.encode or one of its variants).
  87 |     |      */
  88 |     |     function _callOptionalReturn(IERC20 token, bytes memory data) private {
  89 |     |         // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
  90 |     |         // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
  91 |     |         // the target address contains contract code and also asserts for success in the low-level call.
  92 |     | 
  93 |     |         bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
  94 |     |         if (returndata.length > 0) {
  95 |     |             // Return data is optional
  96 |     |             require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
  97 |     |         }
  98 |     |     }
  99 |     | }
 100 |     | 

/opt/scfuzzbench/work/target/lib/openzeppelin-contracts/contracts/utils/Address.sol
   1 |     | // SPDX-License-Identifier: MIT
   2 |     | // OpenZeppelin Contracts v4.4.1 (utils/Address.sol)
   3 |     | 
   4 |     | pragma solidity ^0.8.0;
   5 |     | 
   6 |     | /**
   7 |     |  * @dev Collection of functions related to the address type
   8 |     |  */
   9 |     | library Address {
  10 |     |     /**
  11 |     |      * @dev Returns true if `account` is a contract.
  12 |     |      *
  13 |     |      * [IMPORTANT]
  14 |     |      * ====
  15 |     |      * It is unsafe to assume that an address for which this function returns
  16 |     |      * false is an externally-owned account (EOA) and not a contract.
  17 |     |      *
  18 |     |      * Among others, `isContract` will return false for the following
  19 |     |      * types of addresses:
  20 |     |      *
  21 |     |      *  - an externally-owned account
  22 |     |      *  - a contract in construction
  23 |     |      *  - an address where a contract will be created
  24 |     |      *  - an address where a contract lived, but was destroyed
  25 |     |      * ====
  26 |     |      */
  27 |     |     function isContract(address account) internal view returns (bool) {
  28 |     |         // This method relies on extcodesize, which returns 0 for contracts in
  29 |     |         // construction, since the code is only stored at the end of the
  30 |     |         // constructor execution.
  31 |     | 
  32 |     |         uint256 size;
  33 |     |         assembly {
  34 |     |             size := extcodesize(account)
  35 |     |         }
  36 |     |         return size > 0;
  37 |     |     }
  38 |     | 
  39 |     |     /**
  40 |     |      * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
  41 |     |      * `recipient`, forwarding all available gas and reverting on errors.
  42 |     |      *
  43 |     |      * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
  44 |     |      * of certain opcodes, possibly making contracts go over the 2300 gas limit
  45 |     |      * imposed by `transfer`, making them unable to receive funds via
  46 |     |      * `transfer`. {sendValue} removes this limitation.
  47 |     |      *
  48 |     |      * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
  49 |     |      *
  50 |     |      * IMPORTANT: because control is transferred to `recipient`, care must be
  51 |     |      * taken to not create reentrancy vulnerabilities. Consider using
  52 |     |      * {ReentrancyGuard} or the
  53 |     |      * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
  54 |     |      */
  55 |     |     function sendValue(address payable recipient, uint256 amount) internal {
  56 |     |         require(address(this).balance >= amount, "Address: insufficient balance");
  57 |     | 
  58 |     |         (bool success, ) = recipient.call{value: amount}("");
  59 |     |         require(success, "Address: unable to send value, recipient may have reverted");
  60 |     |     }
  61 |     | 
  62 |     |     /**
  63 |     |      * @dev Performs a Solidity function call using a low level `call`. A
  64 |     |      * plain `call` is an unsafe replacement for a function call: use this
  65 |     |      * function instead.
  66 |     |      *
  67 |     |      * If `target` reverts with a revert reason, it is bubbled up by this
  68 |     |      * function (like regular Solidity function calls).
  69 |     |      *
  70 |     |      * Returns the raw returned data. To convert to the expected return value,
  71 |     |      * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
  72 |     |      *
  73 |     |      * Requirements:
  74 |     |      *
  75 |     |      * - `target` must be a contract.
  76 |     |      * - calling `target` with `data` must not revert.
  77 |     |      *
  78 |     |      * _Available since v3.1._
  79 |     |      */
  80 |     |     function functionCall(address target, bytes memory data) internal returns (bytes memory) {
  81 |     |         return functionCall(target, data, "Address: low-level call failed");
  82 |     |     }
  83 |     | 
  84 |     |     /**
  85 |     |      * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
  86 |     |      * `errorMessage` as a fallback revert reason when `target` reverts.
  87 |     |      *
  88 |     |      * _Available since v3.1._
  89 |     |      */
  90 |     |     function functionCall(
  91 |     |         address target,
  92 |     |         bytes memory data,
  93 |     |         string memory errorMessage
  94 |     |     ) internal returns (bytes memory) {
  95 |     |         return functionCallWithValue(target, data, 0, errorMessage);
  96 |     |     }
  97 |     | 
  98 |     |     /**
  99 |     |      * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
 100 |     |      * but also transferring `value` wei to `target`.
 101 |     |      *
 102 |     |      * Requirements:
 103 |     |      *
 104 |     |      * - the calling contract must have an ETH balance of at least `value`.
 105 |     |      * - the called Solidity function must be `payable`.
 106 |     |      *
 107 |     |      * _Available since v3.1._
 108 |     |      */
 109 |     |     function functionCallWithValue(
 110 |     |         address target,
 111 |     |         bytes memory data,
 112 |     |         uint256 value
 113 |     |     ) internal returns (bytes memory) {
 114 |     |         return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
 115 |     |     }
 116 |     | 
 117 |     |     /**
 118 |     |      * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
 119 |     |      * with `errorMessage` as a fallback revert reason when `target` reverts.
 120 |     |      *
 121 |     |      * _Available since v3.1._
 122 |     |      */
 123 |     |     function functionCallWithValue(
 124 |     |         address target,
 125 |     |         bytes memory data,
 126 |     |         uint256 value,
 127 |     |         string memory errorMessage
 128 |     |     ) internal returns (bytes memory) {
 129 |     |         require(address(this).balance >= value, "Address: insufficient balance for call");
 130 |     |         require(isContract(target), "Address: call to non-contract");
 131 |     | 
 132 |     |         (bool success, bytes memory returndata) = target.call{value: value}(data);
 133 |     |         return verifyCallResult(success, returndata, errorMessage);
 134 |     |     }
 135 |     | 
 136 |     |     /**
 137 |     |      * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
 138 |     |      * but performing a static call.
 139 |     |      *
 140 |     |      * _Available since v3.3._
 141 |     |      */
 142 |     |     function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
 143 |     |         return functionStaticCall(target, data, "Address: low-level static call failed");
 144 |     |     }
 145 |     | 
 146 |     |     /**
 147 |     |      * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
 148 |     |      * but performing a static call.
 149 |     |      *
 150 |     |      * _Available since v3.3._
 151 |     |      */
 152 |     |     function functionStaticCall(
 153 |     |         address target,
 154 |     |         bytes memory data,
 155 |     |         string memory errorMessage
 156 |     |     ) internal view returns (bytes memory) {
 157 |     |         require(isContract(target), "Address: static call to non-contract");
 158 |     | 
 159 |     |         (bool success, bytes memory returndata) = target.staticcall(data);
 160 |     |         return verifyCallResult(success, returndata, errorMessage);
 161 |     |     }
 162 |     | 
 163 |     |     /**
 164 |     |      * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
 165 |     |      * but performing a delegate call.
 166 |     |      *
 167 |     |      * _Available since v3.4._
 168 |     |      */
 169 |     |     function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
 170 |     |         return functionDelegateCall(target, data, "Address: low-level delegate call failed");
 171 |     |     }
 172 |     | 
 173 |     |     /**
 174 |     |      * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
 175 |     |      * but performing a delegate call.
 176 |     |      *
 177 |     |      * _Available since v3.4._
 178 |     |      */
 179 |     |     function functionDelegateCall(
 180 |     |         address target,
 181 |     |         bytes memory data,
 182 |     |         string memory errorMessage
 183 |     |     ) internal returns (bytes memory) {
 184 |     |         require(isContract(target), "Address: delegate call to non-contract");
 185 |     | 
 186 |     |         (bool success, bytes memory returndata) = target.delegatecall(data);
 187 |     |         return verifyCallResult(success, returndata, errorMessage);
 188 |     |     }
 189 |     | 
 190 |     |     /**
 191 |     |      * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
 192 |     |      * revert reason using the provided one.
 193 |     |      *
 194 |     |      * _Available since v4.3._
 195 |     |      */
 196 |     |     function verifyCallResult(
 197 |     |         bool success,
 198 |     |         bytes memory returndata,
 199 |     |         string memory errorMessage
 200 |     |     ) internal pure returns (bytes memory) {
 201 |     |         if (success) {
 202 |     |             return returndata;
 203 |     |         } else {
 204 |     |             // Look for revert reason and bubble it up if present
 205 |     |             if (returndata.length > 0) {
 206 |     |                 // The easiest way to bubble the revert reason is using memory via assembly
 207 |     | 
 208 |     |                 assembly {
 209 |     |                     let returndata_size := mload(returndata)
 210 |     |                     revert(add(32, returndata), returndata_size)
 211 |     |                 }
 212 |     |             } else {
 213 |     |                 revert(errorMessage);
 214 |     |             }
 215 |     |         }
 216 |     |     }
 217 |     | }
 218 |     | 

/opt/scfuzzbench/work/target/lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol
   1 |     | // SPDX-License-Identifier: MIT
   2 |     | // OpenZeppelin Contracts v4.4.1 (utils/math/SafeCast.sol)
   3 |     | 
   4 |     | pragma solidity ^0.8.0;
   5 |     | 
   6 |     | /**
   7 |     |  * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
   8 |     |  * checks.
   9 |     |  *
  10 |     |  * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
  11 |     |  * easily result in undesired exploitation or bugs, since developers usually
  12 |     |  * assume that overflows raise errors. `SafeCast` restores this intuition by
  13 |     |  * reverting the transaction when such an operation overflows.
  14 |     |  *
  15 |     |  * Using this library instead of the unchecked operations eliminates an entire
  16 |     |  * class of bugs, so it's recommended to use it always.
  17 |     |  *
  18 |     |  * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
  19 |     |  * all math on `uint256` and `int256` and then downcasting.
  20 |     |  */
  21 |     | library SafeCast {
  22 |     |     /**
  23 |     |      * @dev Returns the downcasted uint224 from uint256, reverting on
  24 |     |      * overflow (when the input is greater than largest uint224).
  25 |     |      *
  26 |     |      * Counterpart to Solidity's `uint224` operator.
  27 |     |      *
  28 |     |      * Requirements:
  29 |     |      *
  30 |     |      * - input must fit into 224 bits
  31 |     |      */
  32 |     |     function toUint224(uint256 value) internal pure returns (uint224) {
  33 |     |         require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
  34 |     |         return uint224(value);
  35 |     |     }
  36 |     | 
  37 |     |     /**
  38 |     |      * @dev Returns the downcasted uint128 from uint256, reverting on
  39 |     |      * overflow (when the input is greater than largest uint128).
  40 |     |      *
  41 |     |      * Counterpart to Solidity's `uint128` operator.
  42 |     |      *
  43 |     |      * Requirements:
  44 |     |      *
  45 |     |      * - input must fit into 128 bits
  46 |     |      */
  47 |     |     function toUint128(uint256 value) internal pure returns (uint128) {
  48 |     |         require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
  49 |     |         return uint128(value);
  50 |     |     }
  51 |     | 
  52 |     |     /**
  53 |     |      * @dev Returns the downcasted uint96 from uint256, reverting on
  54 |     |      * overflow (when the input is greater than largest uint96).
  55 |     |      *
  56 |     |      * Counterpart to Solidity's `uint96` operator.
  57 |     |      *
  58 |     |      * Requirements:
  59 |     |      *
  60 |     |      * - input must fit into 96 bits
  61 |     |      */
  62 |     |     function toUint96(uint256 value) internal pure returns (uint96) {
  63 |     |         require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
  64 |     |         return uint96(value);
  65 |     |     }
  66 |     | 
  67 |     |     /**
  68 |     |      * @dev Returns the downcasted uint64 from uint256, reverting on
  69 |     |      * overflow (when the input is greater than largest uint64).
  70 |     |      *
  71 |     |      * Counterpart to Solidity's `uint64` operator.
  72 |     |      *
  73 |     |      * Requirements:
  74 |     |      *
  75 |     |      * - input must fit into 64 bits
  76 |     |      */
  77 |     |     function toUint64(uint256 value) internal pure returns (uint64) {
  78 |     |         require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
  79 |     |         return uint64(value);
  80 |     |     }
  81 |     | 
  82 |     |     /**
  83 |     |      * @dev Returns the downcasted uint32 from uint256, reverting on
  84 |     |      * overflow (when the input is greater than largest uint32).
  85 |     |      *
  86 |     |      * Counterpart to Solidity's `uint32` operator.
  87 |     |      *
  88 |     |      * Requirements:
  89 |     |      *
  90 |     |      * - input must fit into 32 bits
  91 |     |      */
  92 |     |     function toUint32(uint256 value) internal pure returns (uint32) {
  93 |     |         require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
  94 |     |         return uint32(value);
  95 |     |     }
  96 |     | 
  97 |     |     /**
  98 |     |      * @dev Returns the downcasted uint16 from uint256, reverting on
  99 |     |      * overflow (when the input is greater than largest uint16).
 100 |     |      *
 101 |     |      * Counterpart to Solidity's `uint16` operator.
 102 |     |      *
 103 |     |      * Requirements:
 104 |     |      *
 105 |     |      * - input must fit into 16 bits
 106 |     |      */
 107 |     |     function toUint16(uint256 value) internal pure returns (uint16) {
 108 |     |         require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
 109 |     |         return uint16(value);
 110 |     |     }
 111 |     | 
 112 |     |     /**
 113 |     |      * @dev Returns the downcasted uint8 from uint256, reverting on
 114 |     |      * overflow (when the input is greater than largest uint8).
 115 |     |      *
 116 |     |      * Counterpart to Solidity's `uint8` operator.
 117 |     |      *
 118 |     |      * Requirements:
 119 |     |      *
 120 |     |      * - input must fit into 8 bits.
 121 |     |      */
 122 |     |     function toUint8(uint256 value) internal pure returns (uint8) {
 123 |     |         require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
 124 |     |         return uint8(value);
 125 |     |     }
 126 |     | 
 127 |     |     /**
 128 |     |      * @dev Converts a signed int256 into an unsigned uint256.
 129 |     |      *
 130 |     |      * Requirements:
 131 |     |      *
 132 |     |      * - input must be greater than or equal to 0.
 133 |     |      */
 134 | *   |     function toUint256(int256 value) internal pure returns (uint256) {
 135 | *   |         require(value >= 0, "SafeCast: value must be positive");
 136 |     |         return uint256(value);
 137 |     |     }
 138 |     | 
 139 |     |     /**
 140 |     |      * @dev Returns the downcasted int128 from int256, reverting on
 141 |     |      * overflow (when the input is less than smallest int128 or
 142 |     |      * greater than largest int128).
 143 |     |      *
 144 |     |      * Counterpart to Solidity's `int128` operator.
 145 |     |      *
 146 |     |      * Requirements:
 147 |     |      *
 148 |     |      * - input must fit into 128 bits
 149 |     |      *
 150 |     |      * _Available since v3.1._
 151 |     |      */
 152 |     |     function toInt128(int256 value) internal pure returns (int128) {
 153 |     |         require(value >= type(int128).min && value <= type(int128).max, "SafeCast: value doesn't fit in 128 bits");
 154 |     |         return int128(value);
 155 |     |     }
 156 |     | 
 157 |     |     /**
 158 |     |      * @dev Returns the downcasted int64 from int256, reverting on
 159 |     |      * overflow (when the input is less than smallest int64 or
 160 |     |      * greater than largest int64).
 161 |     |      *
 162 |     |      * Counterpart to Solidity's `int64` operator.
 163 |     |      *
 164 |     |      * Requirements:
 165 |     |      *
 166 |     |      * - input must fit into 64 bits
 167 |     |      *
 168 |     |      * _Available since v3.1._
 169 |     |      */
 170 |     |     function toInt64(int256 value) internal pure returns (int64) {
 171 |     |         require(value >= type(int64).min && value <= type(int64).max, "SafeCast: value doesn't fit in 64 bits");
 172 |     |         return int64(value);
 173 |     |     }
 174 |     | 
 175 |     |     /**
 176 |     |      * @dev Returns the downcasted int32 from int256, reverting on
 177 |     |      * overflow (when the input is less than smallest int32 or
 178 |     |      * greater than largest int32).
 179 |     |      *
 180 |     |      * Counterpart to Solidity's `int32` operator.
 181 |     |      *
 182 |     |      * Requirements:
 183 |     |      *
 184 |     |      * - input must fit into 32 bits
 185 |     |      *
 186 |     |      * _Available since v3.1._
 187 |     |      */
 188 |     |     function toInt32(int256 value) internal pure returns (int32) {
 189 |     |         require(value >= type(int32).min && value <= type(int32).max, "SafeCast: value doesn't fit in 32 bits");
 190 |     |         return int32(value);
 191 |     |     }
 192 |     | 
 193 |     |     /**
 194 |     |      * @dev Returns the downcasted int16 from int256, reverting on
 195 |     |      * overflow (when the input is less than smallest int16 or
 196 |     |      * greater than largest int16).
 197 |     |      *
 198 |     |      * Counterpart to Solidity's `int16` operator.
 199 |     |      *
 200 |     |      * Requirements:
 201 |     |      *
 202 |     |      * - input must fit into 16 bits
 203 |     |      *
 204 |     |      * _Available since v3.1._
 205 |     |      */
 206 |     |     function toInt16(int256 value) internal pure returns (int16) {
 207 |     |         require(value >= type(int16).min && value <= type(int16).max, "SafeCast: value doesn't fit in 16 bits");
 208 |     |         return int16(value);
 209 |     |     }
 210 |     | 
 211 |     |     /**
 212 |     |      * @dev Returns the downcasted int8 from int256, reverting on
 213 |     |      * overflow (when the input is less than smallest int8 or
 214 |     |      * greater than largest int8).
 215 |     |      *
 216 |     |      * Counterpart to Solidity's `int8` operator.
 217 |     |      *
 218 |     |      * Requirements:
 219 |     |      *
 220 |     |      * - input must fit into 8 bits.
 221 |     |      *
 222 |     |      * _Available since v3.1._
 223 |     |      */
 224 |     |     function toInt8(int256 value) internal pure returns (int8) {
 225 |     |         require(value >= type(int8).min && value <= type(int8).max, "SafeCast: value doesn't fit in 8 bits");
 226 |     |         return int8(value);
 227 |     |     }
 228 |     | 
 229 |     |     /**
 230 |     |      * @dev Converts an unsigned uint256 into a signed int256.
 231 |     |      *
 232 |     |      * Requirements:
 233 |     |      *
 234 |     |      * - input must be less than or equal to maxInt256.
 235 |     |      */
 236 | *   |     function toInt256(uint256 value) internal pure returns (int256) {
 237 |     |         // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
 238 | *   |         require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
 239 | *   |         return int256(value);
 240 |     |     }
 241 |     | }
 242 |     | 

/opt/scfuzzbench/work/target/lib/openzeppelin-contracts/contracts/utils/math/SafeMath.sol
   1 |     | // SPDX-License-Identifier: MIT
   2 |     | // OpenZeppelin Contracts v4.4.1 (utils/math/SafeMath.sol)
   3 |     | 
   4 |     | pragma solidity ^0.8.0;
   5 |     | 
   6 |     | // CAUTION
   7 |     | // This version of SafeMath should only be used with Solidity 0.8 or later,
   8 |     | // because it relies on the compiler's built in overflow checks.
   9 |     | 
  10 |     | /**
  11 |     |  * @dev Wrappers over Solidity's arithmetic operations.
  12 |     |  *
  13 |     |  * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
  14 |     |  * now has built in overflow checking.
  15 |     |  */
  16 |     | library SafeMath {
  17 |     |     /**
  18 |     |      * @dev Returns the addition of two unsigned integers, with an overflow flag.
  19 |     |      *
  20 |     |      * _Available since v3.4._
  21 |     |      */
  22 |     |     function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
  23 |     |         unchecked {
  24 |     |             uint256 c = a + b;
  25 |     |             if (c < a) return (false, 0);
  26 |     |             return (true, c);
  27 |     |         }
  28 |     |     }
  29 |     | 
  30 |     |     /**
  31 |     |      * @dev Returns the substraction of two unsigned integers, with an overflow flag.
  32 |     |      *
  33 |     |      * _Available since v3.4._
  34 |     |      */
  35 |     |     function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
  36 |     |         unchecked {
  37 |     |             if (b > a) return (false, 0);
  38 |     |             return (true, a - b);
  39 |     |         }
  40 |     |     }
  41 |     | 
  42 |     |     /**
  43 |     |      * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
  44 |     |      *
  45 |     |      * _Available since v3.4._
  46 |     |      */
  47 |     |     function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
  48 |     |         unchecked {
  49 |     |             // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
  50 |     |             // benefit is lost if 'b' is also tested.
  51 |     |             // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
  52 |     |             if (a == 0) return (true, 0);
  53 |     |             uint256 c = a * b;
  54 |     |             if (c / a != b) return (false, 0);
  55 |     |             return (true, c);
  56 |     |         }
  57 |     |     }
  58 |     | 
  59 |     |     /**
  60 |     |      * @dev Returns the division of two unsigned integers, with a division by zero flag.
  61 |     |      *
  62 |     |      * _Available since v3.4._
  63 |     |      */
  64 |     |     function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
  65 |     |         unchecked {
  66 |     |             if (b == 0) return (false, 0);
  67 |     |             return (true, a / b);
  68 |     |         }
  69 |     |     }
  70 |     | 
  71 |     |     /**
  72 |     |      * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
  73 |     |      *
  74 |     |      * _Available since v3.4._
  75 |     |      */
  76 |     |     function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
  77 |     |         unchecked {
  78 |     |             if (b == 0) return (false, 0);
  79 |     |             return (true, a % b);
  80 |     |         }
  81 |     |     }
  82 |     | 
  83 |     |     /**
  84 |     |      * @dev Returns the addition of two unsigned integers, reverting on
  85 |     |      * overflow.
  86 |     |      *
  87 |     |      * Counterpart to Solidity's `+` operator.
  88 |     |      *
  89 |     |      * Requirements:
  90 |     |      *
  91 |     |      * - Addition cannot overflow.
  92 |     |      */
  93 |     |     function add(uint256 a, uint256 b) internal pure returns (uint256) {
  94 |     |         return a + b;
  95 |     |     }
  96 |     | 
  97 |     |     /**
  98 |     |      * @dev Returns the subtraction of two unsigned integers, reverting on
  99 |     |      * overflow (when the result is negative).
 100 |     |      *
 101 |     |      * Counterpart to Solidity's `-` operator.
 102 |     |      *
 103 |     |      * Requirements:
 104 |     |      *
 105 |     |      * - Subtraction cannot overflow.
 106 |     |      */
 107 |     |     function sub(uint256 a, uint256 b) internal pure returns (uint256) {
 108 |     |         return a - b;
 109 |     |     }
 110 |     | 
 111 |     |     /**
 112 |     |      * @dev Returns the multiplication of two unsigned integers, reverting on
 113 |     |      * overflow.
 114 |     |      *
 115 |     |      * Counterpart to Solidity's `*` operator.
 116 |     |      *
 117 |     |      * Requirements:
 118 |     |      *
 119 |     |      * - Multiplication cannot overflow.
 120 |     |      */
 121 | *   |     function mul(uint256 a, uint256 b) internal pure returns (uint256) {
 122 | *   |         return a * b;
 123 |     |     }
 124 |     | 
 125 |     |     /**
 126 |     |      * @dev Returns the integer division of two unsigned integers, reverting on
 127 |     |      * division by zero. The result is rounded towards zero.
 128 |     |      *
 129 |     |      * Counterpart to Solidity's `/` operator.
 130 |     |      *
 131 |     |      * Requirements:
 132 |     |      *
 133 |     |      * - The divisor cannot be zero.
 134 |     |      */
 135 | *   |     function div(uint256 a, uint256 b) internal pure returns (uint256) {
 136 | *   |         return a / b;
 137 |     |     }
 138 |     | 
 139 |     |     /**
 140 |     |      * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
 141 |     |      * reverting when dividing by zero.
 142 |     |      *
 143 |     |      * Counterpart to Solidity's `%` operator. This function uses a `revert`
 144 |     |      * opcode (which leaves remaining gas untouched) while Solidity uses an
 145 |     |      * invalid opcode to revert (consuming all remaining gas).
 146 |     |      *
 147 |     |      * Requirements:
 148 |     |      *
 149 |     |      * - The divisor cannot be zero.
 150 |     |      */
 151 |     |     function mod(uint256 a, uint256 b) internal pure returns (uint256) {
 152 |     |         return a % b;
 153 |     |     }
 154 |     | 
 155 |     |     /**
 156 |     |      * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
 157 |     |      * overflow (when the result is negative).
 158 |     |      *
 159 |     |      * CAUTION: This function is deprecated because it requires allocating memory for the error
 160 |     |      * message unnecessarily. For custom revert reasons use {trySub}.
 161 |     |      *
 162 |     |      * Counterpart to Solidity's `-` operator.
 163 |     |      *
 164 |     |      * Requirements:
 165 |     |      *
 166 |     |      * - Subtraction cannot overflow.
 167 |     |      */
 168 |     |     function sub(
 169 |     |         uint256 a,
 170 |     |         uint256 b,
 171 |     |         string memory errorMessage
 172 |     |     ) internal pure returns (uint256) {
 173 |     |         unchecked {
 174 |     |             require(b <= a, errorMessage);
 175 |     |             return a - b;
 176 |     |         }
 177 |     |     }
 178 |     | 
 179 |     |     /**
 180 |     |      * @dev Returns the integer division of two unsigned integers, reverting with custom message on
 181 |     |      * division by zero. The result is rounded towards zero.
 182 |     |      *
 183 |     |      * Counterpart to Solidity's `/` operator. Note: this function uses a
 184 |     |      * `revert` opcode (which leaves remaining gas untouched) while Solidity
 185 |     |      * uses an invalid opcode to revert (consuming all remaining gas).
 186 |     |      *
 187 |     |      * Requirements:
 188 |     |      *
 189 |     |      * - The divisor cannot be zero.
 190 |     |      */
 191 |     |     function div(
 192 |     |         uint256 a,
 193 |     |         uint256 b,
 194 |     |         string memory errorMessage
 195 |     |     ) internal pure returns (uint256) {
 196 |     |         unchecked {
 197 |     |             require(b > 0, errorMessage);
 198 |     |             return a / b;
 199 |     |         }
 200 |     |     }
 201 |     | 
 202 |     |     /**
 203 |     |      * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
 204 |     |      * reverting with custom message when dividing by zero.
 205 |     |      *
 206 |     |      * CAUTION: This function is deprecated because it requires allocating memory for the error
 207 |     |      * message unnecessarily. For custom revert reasons use {tryMod}.
 208 |     |      *
 209 |     |      * Counterpart to Solidity's `%` operator. This function uses a `revert`
 210 |     |      * opcode (which leaves remaining gas untouched) while Solidity uses an
 211 |     |      * invalid opcode to revert (consuming all remaining gas).
 212 |     |      *
 213 |     |      * Requirements:
 214 |     |      *
 215 |     |      * - The divisor cannot be zero.
 216 |     |      */
 217 |     |     function mod(
 218 |     |         uint256 a,
 219 |     |         uint256 b,
 220 |     |         string memory errorMessage
 221 |     |     ) internal pure returns (uint256) {
 222 |     |         unchecked {
 223 |     |             require(b > 0, errorMessage);
 224 |     |             return a % b;
 225 |     |         }
 226 |     |     }
 227 |     | }
 228 |     | 

/opt/scfuzzbench/work/target/test/recon/CryticTester.sol
 1 |     | // SPDX-License-Identifier: BUSL-1.1
 2 |     | pragma solidity ^0.8.0;
 3 |     | 
 4 |     | import {Properties} from "./Properties.sol";
 5 |     | 
 6 |     | // echidna test/recon/CryticTester.sol --contract CryticTester --config echidna.yaml
 7 | *r  | contract CryticTester is Properties {}
 8 |     | 

/opt/scfuzzbench/work/target/test/recon/Properties.sol
  1 |     | // SPDX-License-Identifier: BUSL-1.1
  2 |     | pragma solidity ^0.8.0;
  3 |     | 
  4 |     | import {Echidna} from "../../contracts/contracts/echidna/Echidna.sol";
  5 |     | 
  6 |     | /// @notice scfuzzbench adaptation layer: canary checks on top of the
  7 |     | /// upstream OUSD Echidna suite. Assertion failures are surfaced the same
  8 |     | /// way for Echidna, Medusa, Foundry, and Recon (AssertionFailed event +
  9 |     | /// assert), and dedup to the emitting function name across fuzzers.
 10 |     | abstract contract Properties is Echidna {
 11 |     |     string internal constant ASSERTION_CANARY = "!!! canary assertion";
 12 |     |     string internal constant INVARIANT_CANARY_GLOBAL_INVARIANT_FAILURE = "Canary invariant";
 13 |     | 
 14 |     |     event AssertionFailed(string reason);
 15 |     | 
 16 | *   |     function t(bool b, string memory reason) internal {
 17 | *   |         if (!b) {
 18 | *   |             emit AssertionFailed(reason);
 19 | *   |             assert(false);
 20 |     |         }
 21 |     |     }
 22 |     | 
 23 | *   |     function invariant_canary() public returns (bool) {
 24 | *   |         t(false, INVARIANT_CANARY_GLOBAL_INVARIANT_FAILURE);
 25 |     |         return true;
 26 |     |     }
 27 |     | 
 28 | *   |     function assert_canary_ASSERTION_CANARY(uint256 entropy) public {
 29 | *   |         t(entropy > 0, ASSERTION_CANARY);
 30 |     |     }
 31 |     | }
 32 |     | 

